javascript - Object.create 与直接原型(prototype)继承

标签 javascript ecmascript-5 prototypal-inheritance object-create

我一直在研究 EcmaScript 5 规范中的 Object.create,我正在尝试创建一个多重继承类型结构。

假设我有几个函数:a、b 和 c。只处理原型(prototype),我可以这样做:

function a () {}
a.prototype = {
    fnA = function () {},
    propA = 500
};

function b () {}
b.prototype = a.prototype;
b.prototype.fnB = function () {};
b.prototype.propB = 300;

function c () {}
c.prototype = b.prototype;
c.prototype.fnC = function () {};
c.prototype.propC = 200;

但是使用 Object.create,我会这样做:

function a() {}
a.prototype = {
    fnA = function () {},
    propA = 500
};

var b = Object.create(new a());
b.fnB = function () {};
b.propB = 300;

var c = Object.create(b);
c.fnC = function () {};
c.propC = 200;

我认为两种方式都得到相同的结果。

这看起来有点笨拙,因为我返回对象而不是构造函数。在我看来,进行常规原型(prototype)继承的侵入性较小,对于不需要任何特殊处理即可工作的模块化应用程序更有意义。

我错过了什么吗?尝试通过构造函数来创建 Object.create 有什么好处吗?还是这仅对复制现有对象有用?我只想访问附加到原型(prototype)的属性和函数,而不是后来添加到对象的函数和属性。

或者这个怎​​么样(或者使用更好的深层复制,但想法保持不变)?

function A () {}
A.prototype = {
    fn: function () {
        console.log(this.propA + 30);
    },
    propA: 20
};

function B () {}
Object.keys(A.prototype).forEach(function (item) {
    B.prototype[item] = A.prototype[item];
});
B.prototype.propA = 40;

function C () {}
Object.keys(B.prototype).forEach(function (item) {
    C.prototype[item] = B.prototype[item];
});
C.prototype.fn = function () {
    console.log(this.propA + 3);
};


var a = new A(),
    b = new B(),
    c = new C();

a.fn();
b.fn();
c.fn();

最佳答案

实际上,两种方式都不会得到相同的结果。考虑这一行:

b.prototype = a.prototype;

这样做是将 b.prototype 设置为与 a.prototype 完全相同的对象引用。如果您更改第一个对象(例如通过添加 fnB 方法),您也会更改第二个对象。他们是一样的东西。在第一组代码结束时,您将拥有三个完全相同的原型(prototype),具有相同的方法和属性。

原型(prototype)继承的全部要点是你定义一个“有趣的”对象(也就是说,具有你想要的所有行为)然后用 Object.create 克隆它并修改克隆以满足你的需要(通常通过修改它的属性,而不是它的方法)。

假设您有一个加法器对象:

var adder = {x: 0, y: 0};
adder.execute = function () {
  return this.x + this.y;
}

然后您创建一个克隆并设置其属性:

var myadder = Object.create(adder);
myadder.x = 1;
myadder.y = 2;
console.log(myadder.execute()); // 3

现在显然这是一个愚蠢的例子,但它表明您可以考虑原型(prototype)继承而不必在这些构造函数上编写构造函数和显式原型(prototype)。

关于javascript - Object.create 与直接原型(prototype)继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6338409/

相关文章:

使用 "this = "的 Javascript 函数给出 "Invalid left-hand side in assignment"

javascript - React JS - 未找到 404 中的 Fetch() 事件结果

c++ - 使用正则表达式的条件组匹配

javascript - 检查是否支持 Javascript 删除功能

javascript - JS继承的诡异时刻

javascript - ng-repeat 内的指令双向数据绑定(bind)不起作用

javascript - getUserMedia() 的回调事件

javascript - "location"是 react 中的保留字吗?如果是这样,它有什么作用?

javascript - jQuery/JavaScript - 隐藏/显示单选按钮上挂起的下拉框

javascript - 在 Chrome 中,JS 绑定(bind)函数具有 null arguments.callee.caller