Object.create与直接原型继承



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

假设我有几个函数:a、b和c。只处理原型,我就可以做到这一点:

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;

我想我得到的结果是一样的。

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

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

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

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方法),您也将更改第二个对象。它们是一样的东西。在第一组代码结束时,您将有三个原型,它们都完全相同,具有相同的方法和属性。

原型继承的全部意义在于,定义一个"有趣"的对象(即具有您想要的所有行为),然后用object.创建和修改克隆以满足您的需求(通常通过修改其属性,而不是方法)。

所以假设你有一个加法器对象:

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

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

如果你需要支持不支持Object.create()的浏览器,你可以使用这个

function object(o) {
    function F() {}
    F.prototype = o;
    return new F();
}

对象函数解开了JavaScript的构造函数模式,实现了真正的原型继承。它将一个旧对象作为参数,并返回一个从旧对象继承的空新对象。如果我们试图从新对象中获取成员,但它缺少该键,那么旧对象将提供该成员。对象从对象继承。还有什么比这更面向对象的呢?

更多信息可以在这里阅读:JavaScript 中的原型继承

相关内容

  • 没有找到相关文章

最新更新