我一直在使用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();
答案 0 :(得分:4)
实际上,两种方式都没有得到相同的结果。考虑这一行:
b.prototype = a.prototype;
这样做是将b.prototype
设置为与a.prototype
完全相同的对象引用。如果您更改第一个对象(例如通过添加fnB
方法),您还将更改第二个对象。他们是一样的东西。在第一组代码结束时,您将拥有三个完全相同的原型,具有相同的方法和属性。
原型继承的全部意义在于您定义了一个“有趣”的对象(即,具有您想要的所有行为),然后使用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
现在显然这是一个愚蠢的例子,但是表明你可以想到原型继承,而不必在那些构造函数上编写构造函数和显式原型。
答案 1 :(得分:0)
如果您需要支持不支持Object.create()
的浏览器,可以使用此
function object(o) {
function F() {}
F.prototype = o;
return new F();
}
对象函数解开JavaScript的构造函数模式,实现真正的原型继承。它将旧对象作为参数,并返回一个从旧对象继承的空对象。如果我们尝试从新对象获取成员,并且它缺少该键,则旧对象将提供该成员。对象继承自对象。什么可能比这更面向对象?
更多内容可以在这里阅读:Prototypal Inheritance in JavaScript