继承自Set.prototype

djf*_*dev 5 javascript inheritance set ecmascript-6

这真让我烦恼.我可以轻松地创建一个继承以下方法的新类Array.prototype:

var MyArray = function() {};

MyArray.prototype = Array.prototype;

var myArray = new MyArray();
myArray.push(1); // this is allowed
Run Code Online (Sandbox Code Playgroud)

相同的继承模式似乎不适用于Set.prototype:

var MySet = function() {};

MySet.prototype = Set.prototype;

var mySet = new MySet();
mySet.add(1); // TypeError: Method Set.prototype.add called on incompatible receiver
Run Code Online (Sandbox Code Playgroud)

这是一个实施问题吗?是否有另一种继承模式可行?我在节点v0.12和Canary中尝试了相同的结果.

编辑:这个解决方案有效,但我仍然不确定为什么上述方法不起作用:

var MySet = function(array) {
  var inst = new Set(array);
  inst.__proto__ = MySet.prototype;
  return inst;
}

MySet.prototype = Object.create(Set.prototype);
Run Code Online (Sandbox Code Playgroud)

Ber*_*rgi 4

这是执行问题吗?还有其他可行的继承模式吗?

不,根据规范,这种行为是正确的。这些Set方法必须在实际集合(使用特定于集合的内部槽初始化的对象)上调用,并且不像方法那样通用Array(基本上适用于具有属性的所有内容.length)。

正如规范所述

构造Set函数被设计为可子类化。它可以用作定义extends子句中的值class。打算继承指定Set行为的子类构造函数必须包含superSet构造函数的调用,以使用支持Set.prototype内置方法所需的内部状态来创建和初始化子类实例。

所以你必须使用 ES6 类语法来继承内置函数。

class MySet extends Set {} // default constructor has super() call

var mySet = new MySet();
mySet.add(1);
Run Code Online (Sandbox Code Playgroud)

是否支持此子类化取决于实现,并非所有运行时和转译器都兼容 ES6。