javascript - 为什么要用 `Boy.prototype = new Human;`来模拟继承呢?

标签 javascript ecmascript-5

我不明白为什么每个人都在使用 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/

相关文章:

javascript - 我如何切换声明的变量 slideIndex 以将其放入对象中?

javascript - 如何使用 javascript 最有效地从该 html 字符串中提取内容? (最高性能 = 最低毫秒)

c# - Jint 数组函数 ECMA 5.1

javascript - 哪些(javascript)环境支持 ECMAscript 5 严格模式? (又名 "use strict")

javascript - 是否可以使用 "create"作为 JavaScript 对象文字中的属性名称?

javascript - 用于保存网站文本的书签

javascript - jQuery.off 不使用变量函数名称

javascript - 从服务器端通过 json 返回总和

javascript - 将 array.prototype.foreach() 的结果保存到一个 undefined variable 中

javascript - 通过 javascript 或 jquery 删除特定 div 索引后的任何子元素