Saturday, May 11, 2024
32
rated 0 times [  39] [ 7]  / answers: 1 / hits: 25151  / 9 Years ago, fri, november 13, 2015, 12:00:00

I typically implement inheritance along the following lines.



function Animal () { this.x = 0; this.y = 0;}

Animal.prototype.locate = function() {
console.log(this.x, this.y);
return this;
};
Animal.prototype.move = function(x, y) {
this.x = this.x + x;
this.y = this.y + y;
return this;
}


function Duck () {
Animal.call(this);
}

Duck.prototype = new Animal();
Duck.prototype.constructor = Duck;
Duck.prototype.speak = function () {
console.log(quack);
return this;
}

var daffy = new Duck();

daffy.move(6, 7).locate().speak();


I've read this post by Eric Elliott and if I understand correctly I can use Object.create and Object.assign instead? Is it really that simple?



var animal = {
x : 0,
y : 0,
locate : function () {
console.log(this.x, this.y);
return this;
},
move : function (x, y) {
this.x = this.x + x;
this.y = this.y + y;
return this;
}
}

var duck = function () {
return Object.assign(Object.create(animal), {
speak : function () {
console.log(quack);
return this;
}
});
}

var daffy = duck();

daffy.move(6, 7).locate().speak();


As an aside, by convention constructor functions are capitalized, should object literals that act as constructors also be capitalized?



I realise there are many questions here discussing new versus Object.create, but they typically seem to relate to Duck.prototype = new Animal(); versus Duck.prototype = Object.create(Animal.prototype);


More From » ecmascript-6

 Answers
3

Yes, it is that simple. In your example with Object.create/Object.assign, you are using a factory function to create new instances of duck (similar to the way jQuery creates new instances if you select an element with var body = $('body')). An advantage of this code style is, that it doesn't force you to call a constructor of animal when you want to create a new duck instance (as opposed to ES2015 Classes).



Differences in initialization



Maybe one interesting tidbit that works slightly differently than if you were to use a constructor (or any other initialization function):



When you create a duck instace, all the properties of animal are in the [[Prototype]] slot of the duck instance.



var daffy = duck();
console.log(daffy); // Object { speak: function() }


So daffy does not have any own x and y properties yet. However, when you call the following, they will be added:



daffy.move(6, 7);
console.log(daffy); // Object { speak: function(), x: 6, y: 7 }


Why? In the function-body of animal.move, we have the following statement:



this.x = this.x + x; 


So when you call this with daffy.move, this refers to daffy. So it will try to assign this.x + x to this.x. Since this.x is not yet defined, the [[Prototype]] chain of daffy is traversed down to animal, where animal.x is defined.



Thus in the first call, the this.x on the right side of the assignment refers to animal.x, because daffy.x is not defined. The second time daffy.move(1,2) is called, this.x on the right side will be daffy.x.



Alternative Syntax



Alternatively, you could also use Object.setPrototypeOf instead of Object.create/Object.assign (OLOO Style):



var duck = function () {
var duckObject = {
speak : function () {
console.log(quack);
return this;
}
};
return Object.setPrototypeOf(duckObject, animal);
}


Naming Conventions



I'm not aware of any established conventions. Kyle Simpson uses uppercase letters in OLOO, Eric Elliot seems to use lowercase. Personally I would stick with lower-case, because the object literals that act as constructors are already fully fledged objects themselves (not just blueprint, like classes would be).



Singleton



If you only wanted a single instance (e.g. for a singleton), you could just call it directly:



var duck = Object.assign(Object.create(animal), {
speak : function () {
console.log(quack);
return this;
}
});

duck.move(6, 7).locate().speak();

[#64406] Wednesday, November 11, 2015, 9 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
daphnew

Total Points: 716
Total Questions: 113
Total Answers: 113

Location: Bonaire
Member since Sat, May 1, 2021
3 Years ago
;