在不使用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
更像是一个(标识?)函数/方法,它返回其调用时间this
上下文的引用。所以它是可有可无的。
从上面的评论...
因此,真正的问题是..."
Object.create(basicPrototype.prototype)
和Object.create(basicPrototype)
的对象创建有什么区别?">
很明显,前者创建了一个新对象,basicPrototype.prototype
设置为新对象的原型,后者创建了一个具有basicPrototype
设置为新对象原型的功能的对象......
。这意味着这两种情况下的呼叫/发送sayHi
on/tobasicObj
在技术上是相同的。由于basicObj
没有这样的属性,因此将查找两个对象的原型链。
这两种方法都可以立即找到,因为两个原型都将sayHi
作为自己的属性,这对于前一种情况是清楚的,但(对于某些人来说)对于后一种情况来说可能令人惊讶。(我不得不自己看两遍/三遍,然后再复查。第二个示例确实实现并将sayHi
作为直接属性分配给函数basicPrototype
。因此,对于后一种情况,该函数主要充当转储对象,就像basicPrototype.prototype
对前一种情况所做的那样。
作为最后的结论,人们可以说。示例代码是一个棘手的脑筋急转弯,其中不涉及任何与类相关的内容(就构造函数和构造函数原型而言)。一切都是通过类/构造函数实现的,而不是Object.create
的替代方案。其余的只是棘手的、无害的混淆。