使用或不使用 .prototype 定义 class
Defining a class with or without the .prototype
在没有使用class
关键字的情况下,下面两种构造继承对象的方式有什么区别?在第一个中,我在 .prototype
上附加了东西,而在第二个中,我直接在函数上进行了附加。会有什么区别?
function basicPrototype(){};
basicPrototype.prototype.sayHi = function(name){
console.log("Hello,", name);
}
function basicConstructor() {
return this; // make sure to pass it a this
}
let basicObj = basicConstructor.call(Object.create(basicPrototype.prototype));
basicObj.sayHi("Tommy");
并删除两行的 .prototype
?
function basicPrototype(){};
basicPrototype.sayHi = function(name){
console.log("Hello,", name);
}
function basicConstructor() {
return this; // make sure to pass it a this
}
let basicObj = basicConstructor.call(Object.create(basicPrototype));
basicObj.sayHi("Tommy");
两个示例的代码都可以清理,因为 basicConstructor.call
对不久前通过 Object.reate
创建的传递对象没有任何影响。
此外 basicConstructor
尽管它的名字根本不是构造函数,因为它从未创建实例,因为它从未被 new
调用过。 (它也没有任何实现,既不在函数体内也不在自己的原型实现中。)因此 basicConstructor
更像是一个(身份?)function/method 其中 returns 其调用时间的引用this
上下文。所以可有可无。
从以上评论...
Thus, the real question is ... "What is the difference in between the object creation of Object.create(basicPrototype.prototype)
and Object.create(basicPrototype)
?"
很明显,前者创建一个新对象,并将 basicPrototype.prototype
设置为新对象的原型,后者创建一个对象,其函数 basicPrototype
设置为新对象的原型...
... 这意味着这两种情况的 calling/sending sayHi
on/to basicObj
在技术上是相同的。由于 basicObj
没有这样一个自己的 属性,因此将查找两个对象的原型链。
这两种方法都会立即被发现,因为两个原型都以 sayHi
作为它们自己的 属性,这对于前一种情况来说很明显,但(对于某些人来说)对于后一种情况可能会令人惊讶。 (我不得不亲自查看 twice/three 次并再次核对。)第二个示例确实实现了 sayHi
并将其直接 属性 分配给函数 basicPrototype
。因此,对于后一种情况,该函数主要充当转储对象,就像 basicPrototype.prototype
对前一种情况所做的那样。
作为最后的结论,可以说。示例代码是一个棘手的脑筋急转弯,其中不涉及任何 class 相关(就构造函数和构造函数原型而言)。一切都通过 class/constructor 更少的 Object.create
替代来实现。剩下的只是棘手的、无害的混淆。
在没有使用class
关键字的情况下,下面两种构造继承对象的方式有什么区别?在第一个中,我在 .prototype
上附加了东西,而在第二个中,我直接在函数上进行了附加。会有什么区别?
function basicPrototype(){};
basicPrototype.prototype.sayHi = function(name){
console.log("Hello,", name);
}
function basicConstructor() {
return this; // make sure to pass it a this
}
let basicObj = basicConstructor.call(Object.create(basicPrototype.prototype));
basicObj.sayHi("Tommy");
并删除两行的 .prototype
?
function basicPrototype(){};
basicPrototype.sayHi = function(name){
console.log("Hello,", name);
}
function basicConstructor() {
return this; // make sure to pass it a this
}
let basicObj = basicConstructor.call(Object.create(basicPrototype));
basicObj.sayHi("Tommy");
两个示例的代码都可以清理,因为 basicConstructor.call
对不久前通过 Object.reate
创建的传递对象没有任何影响。
此外 basicConstructor
尽管它的名字根本不是构造函数,因为它从未创建实例,因为它从未被 new
调用过。 (它也没有任何实现,既不在函数体内也不在自己的原型实现中。)因此 basicConstructor
更像是一个(身份?)function/method 其中 returns 其调用时间的引用this
上下文。所以可有可无。
从以上评论...
Thus, the real question is ... "What is the difference in between the object creation of
Object.create(basicPrototype.prototype)
andObject.create(basicPrototype)
?"
很明显,前者创建一个新对象,并将 basicPrototype.prototype
设置为新对象的原型,后者创建一个对象,其函数 basicPrototype
设置为新对象的原型...
... 这意味着这两种情况的 calling/sending sayHi
on/to basicObj
在技术上是相同的。由于 basicObj
没有这样一个自己的 属性,因此将查找两个对象的原型链。
这两种方法都会立即被发现,因为两个原型都以 sayHi
作为它们自己的 属性,这对于前一种情况来说很明显,但(对于某些人来说)对于后一种情况可能会令人惊讶。 (我不得不亲自查看 twice/three 次并再次核对。)第二个示例确实实现了 sayHi
并将其直接 属性 分配给函数 basicPrototype
。因此,对于后一种情况,该函数主要充当转储对象,就像 basicPrototype.prototype
对前一种情况所做的那样。
作为最后的结论,可以说。示例代码是一个棘手的脑筋急转弯,其中不涉及任何 class 相关(就构造函数和构造函数原型而言)。一切都通过 class/constructor 更少的 Object.create
替代来实现。剩下的只是棘手的、无害的混淆。