我不明白为什么每个人都在使用 Boy.prototype = new Human;
来模拟继承。看,我们想要的是 A 的函数吗?我们可以在不实例化一个新 A 的情况下做到这一点(事实上,实例化一个新 A 确实会给我们带来不良结果,因为我们实际上正在运行实例化函数,这不是我们想要的)
那么这不是更好的解决方案吗?
for (var prop_name in Human.prototype) {
Object.defineProperty(
Boy.prototype,
prop_name,
Object.getOwnPropertyDescriptor(Human.prototype,prop_name)
);
}
假设我们是如此特殊并且不仅想要 Human.prototype 中的可枚举属性,我们仍然可以通过使用 Object.getOwnPropertyNames
并在原型(prototype)链上调用它来实现它,而原型(prototype)链又可用于我们通过 Object.getPrototypeOf
。
那么当我们有更好的选择时,使用 Boy.prototype = new Human;
来模拟继承到底有什么好处呢?
最佳答案
更好的选择是创建一个中间体来保存原型(prototype)。
function extend(clazz, superclass) {
var intermediate = function() {};
intermediate.prototype = superclass.prototype;
clazz.prototype = new intermediate();
// Following line is optional, but useful
clazz.prototype.constructor = clazz;
}
这避免了不必要的复制,但仍然意味着您不需要实例化将在其构造函数中工作的对象。它还设置了原型(prototype)链,以便您可以使用 instanceof。它也不会导致某些继承反模式可能导致的父类(super class)原型(prototype)污染。
为了完整性,您的子类应该在其构造函数中调用父类(super class)构造函数,您可以使用 Superclass.call(this);
来完成。
编辑:从 ES5 开始,您可以将对 extend
的调用替换为
Subclass.prototype = Object.create(Superclass.prototype);
它做同样的事情。
关于javascript - 为什么要用 `Boy.prototype = new Human;`来模拟继承呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5991152/