在没有__proto__的情况下配置[[Prototype]]链

时间:2015-03-09 16:24:13

标签: javascript

我想编写一个函数来配置原型链,但我想避免直接使用__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' }

1 个答案:

答案 0 :(得分:2)

要配置原型链,请写入构造函数的.prototype属性,而不是改变现有原型对象的[[prototype]]。当然,您需要将所有属性从旧原型复制到新原型,这通常仅在继承过程完成后才设置。

  

将此描述为mixins的实现是否正确?

没有。 Mixins不会改变从中继承的对象。您的函数不进行多重继承(其中Foo继承自BarBam),但是单个继承链(其中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; } 的主要缺点是并非所有浏览器都支持它。