继承自 Set.prototype
这真的让我很烦.我可以轻松地创建一个继承 Array.prototype
方法的新类:
var MyArray = function() {};MyArray.prototype = Array.prototype;var myArray = new MyArray();myArray.push(1);//这是允许的
同样的继承模式似乎不适用于 Set.prototype
:
var MySet = function() {};MySet.prototype = Set.prototype;var mySet = new MySet();mySet.add(1);//TypeError: 方法 Set.prototype.add 在不兼容的接收器上调用
这是一个实施问题吗?是否有另一种可以工作的继承模式?我已经在节点 v0.12 和 Canary 中尝试过,结果相同.
这个解决方案有效,但我仍然不确定为什么上面的工作不一样:
var MySet = function(array) {var inst = new Set(array);inst.__proto__ = MySet.prototype;返回机构;}MySet.prototype = Object.create(Set.prototype);
解决方案 这是一个实施问题吗?是否有另一种继承模式可行?
不,按照规范,这种行为是正确的.Set
方法必须在实际集合(使用集合特定的内部槽初始化的对象)上调用,并且不像 Array
方法(基本上适用于所有具有.length
属性).
正如规范声明:p><块引用>
Set
构造函数被设计为可子类化.它可以用来作为 class
定义的 extends
子句中的值.子类打算继承指定 Set
行为的构造函数必须包括对 Set
构造函数的 super
调用以创建和用必要的内部状态初始化子类实例支持 Set.prototype
内置方法.
所以你将不得不使用 ES6 类语法来继承内置函数.
class MySet extends Set {}//默认构造函数有 super() 调用var mySet = new MySet();mySet.add(1);
是否支持这种子类化取决于实现,并非所有运行时和转译器都符合 ES6.
This is really bugging me. I can easily create a new class that inherits methods from Array.prototype
:
var MyArray = function() {};
MyArray.prototype = Array.prototype;
var myArray = new MyArray();
myArray.push(1); // this is allowed
The same inheritance pattern doesn't seem to work with 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
Is this an implementation issue? Is there another inheritance pattern that will work? I've tried this in node v0.12 and Canary with the same results.
EDIT: This solution works, but I'm still not sure why the above doesn't work the same:
var MySet = function(array) {
var inst = new Set(array);
inst.__proto__ = MySet.prototype;
return inst;
}
MySet.prototype = Object.create(Set.prototype);
解决方案
Is this an implementation issue? Is there another inheritance pattern that will work?
No, this behaviour is correct as by the spec. The Set
methods must be invoked on actual sets (objects initialised with set-specific internal slots), and are not generic as the Array
methods (which basically work on everything that has a .length
property).
As the spec states:
The
Set
constructor is designed to be subclassable. It may be used as the value in anextends
clause of aclass
definition. Subclass constructors that intend to inherit the specifiedSet
behaviour must include asuper
call to theSet
constructor to create and initialize the subclass instance with the internal state necessary to support theSet.prototype
built-in methods.
So you will have to use ES6 class syntax to inherit from the built-ins.
class MySet extends Set {} // default constructor has super() call
var mySet = new MySet();
mySet.add(1);
Whether this subclassing is supported depends on the implementation, not all runtimes and transpilers are ES6-compliant yet.
相关文章