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();
我已经读过this post by Eric Elliott,如果我理解正确,我可以使用Object.create和Object.assign?真的那么简单吗?
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();
除此之外,通过构造函数的大小写,应该对作为构造函数的文字进行大写化?
我意识到这里有很多问题讨论新的和Object.create,但它们通常似乎与Duck.prototype = new Animal()有关;而Duck.prototype = Object.create(Animal.prototype);
解决方法
初始化差异
也许一个有趣的tidbit与使用构造函数(或任何其他初始化函数)的工作方式略有不同:
当你创建一个鸭子instace时,动物的所有属性都在鸭子实例的[[Prototype]]插槽中.
var daffy = duck();
console.log(daffy); // Object { speak: function() }
所以daffy还没有任何自己的x和y属性.但是,当您调用以下内容时,将添加它们:
daffy.move(6,7);
console.log(daffy); // Object { speak: function(),x: 6,y: 7 }
为什么?在动物的功能体中,我们有以下语句:
this.x = this.x + x;
所以当你用daffy.move打电话时,这是指daffy.所以它将尝试将this.x x分配给this.x.由于这个x还没有定义,所以daffy的[[Prototype]]链被遍历到动物,在这里定义了animal.x.
因此在第一次调用中,分配的右侧的this.x指的是animal.x,因为没有定义daffy.x.第二次调用daffy.move(1,2),右边的this.x将是daffy.x.
替代语法
或者,您也可以使用Object.setPrototypeOf而不是Object.create / Object.assign(OLOO Style):
var duck = function () {
var duckObject = {
speak : function () {
console.log("quack");
return this;
}
};
return Object.setPrototypeOf(duckObject,animal);
}
命名约定
我不知道任何既定的惯例.凯尔辛普森在OLOO中使用大写字母,埃利奥利似乎使用小写字母.就个人而言,我会坚持使用小写,因为作为构造函数的对象文字已经是完全成熟的对象本身(不只是蓝图,就像类).
独生子
如果你只想要一个单一的实例(例如单例),你可以直接调用它:
var duck = Object.assign(Object.create(animal),{
speak : function () {
console.log("quack");
return this;
}
});
duck.move(6,7).locate().speak();