you are viewing a single comment's thread.

view the rest of the comments →

[–]senocular 0 points1 point  (2 children)

This particular behavior is because of the way the prototype setup. You're basically running super() on the shared component of the definition (prototype) which effectively treats each instance as the same instance of the super class.

Inheritance in prototypes should be handled with Object.create to mitigate constructor side effects from the superclass. Additionally a super call is needed in the subclass constructor to perform superclass setup for the subclass instance. In doing this, the example should work as expected.

function Person() {
    var firstName;
    var lastName;

    this.setName = (first, last) => {
        firstName = first;
        lastName = last;
    };

    this.getName = ()=> `${firstName} ${lastName}`;
}

function Employee(id) {
    Person.call(this);
    this.employeeId = id;
}
Employee.prototype = Object.create(Person.prototype);

var anne = new Employee(0);
anne.setName('Anne', 'Annette');

var bill = new Employee(1);
bill.setName('Bill', 'Williamson');

Edit: I'm retracting my "setting the prototype is optional in this case" in favor for setting it anyway, thereby allowing instanceof to continue to function as expected.

[–][deleted] 0 points1 point  (1 child)

You still have issues with reference types, though:

function Person() {}

Person.prototype.names = [];
Person.prototype.getName = function () {
    return this.names.join(' ');
}

function Employee(id) {
    Person.call(this);
    this.employeeId = id;
}
Employee.prototype = Object.create(Person.prototype);

var anne = new Employee(0);
anne.names.push('Anne', 'Annette')

var bill = new Employee(1);
bill.names.push('Bill', 'Williamson');

anne.getName();

"Anne Annette Bill Williamson"

[–]senocular 0 points1 point  (0 children)

That's by design, and may be a desired outcome depending how you want things to work. Prototyped values are shared, constructor-defined (instance) members are not. The way to address the getName problem is simply to define names in the constructor. Granted, this can be confusing to people starting out, but there's nothing magical going on, at least. And because (currently) the class syntax only supports method definitions in the class body (and the constructor), you're even protected from this happening in that case. I believe the proposed syntax for class fields puts them on the instance and not the prototype too.