我想编写一个函数来配置原型链,但我想避免直接使用__proto__
或Object.setPrototypeOf
。可以这样做吗?如果不是,那么从性能上看是否更可取?
另外,将此描述为mixins的实现是否正确?
这就是我所拥有的(使用__proto__
):
function mix(fn) {
var ancestorFns, curr
if (typeof fn !== 'function') {
throw 'fn must be a function.';
}
ancestorFns = Array.prototype.slice.call(arguments, 1);
curr = fn.prototype;
ancestorFns.forEach(function(ancestorFn) {
if (typeof ancestorFn !== 'function') {
throw 'ancestorFn must be a function.';
}
curr = curr.__proto__ = ancestorFn.prototype;
});
}
用法:
function Foo() {}
Foo.prototype.a = 'a';
function Bar() {}
Bar.prototype.b = 'b';
function Bam() {}
Bam.prototype.c = 'c';
mix(Foo, Bar, Bam);
console.dir(Foo.prototype); // { a: 'a' }
console.dir(Foo.prototype.__proto__); // { b: 'b' }
console.dir(Foo.prototype.__proto__.__proto__); // { c: 'c' }
答案 0 :(得分:2)
要配置原型链,请写入构造函数的.prototype
属性,而不是改变现有原型对象的[[prototype]]。当然,您需要将所有属性从旧原型复制到新原型,这通常仅在继承过程完成后才设置。
将此描述为mixins的实现是否正确?
没有。 Mixins不会改变从中继承的对象。您的函数不进行多重继承(其中Foo
继承自Bar
和Bam
),但是单个继承链(其中Foo
继承自{{1} }和Bar
继承自Bar
)。
当然,你的功能使用原型继承,而术语" mixin"指的是将方法复制到对象上(至少在JS中)。
可以这样做吗?
我要通过这个(相当标准的)实现:
Bam
要么表现更好吗?
我不确定原型对象的[[prototype]]实际上是多么糟糕 - 如果在构造任何实例之前完成它。你应该测试自己,我很确定你不会获得巨大的性能差异。当然,function inherit(child, parent) {
if (arguments.length > 2)
parent = inherit.apply(this, Array.prototype.slice.call(arguments, 1));
child.prototype = Object.create(
parent.prototype,
// get all property descriptor objects from the old child.prototype
// will include `constructor` and all manually set properties
Object.getOwnPropertyNames(child.prototype).reduce(function(m, n) {
m[n] = Object.getOwnPropertyDescriptor(child.prototype, n);
return m;
}, {})
);
return child;
}
的主要缺点是并非所有浏览器都支持它。