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();