[英]Extending Array with ES6 classes
我听说ES6现在最终允许子类化Array。 这是一个给出的例子
class Stack extends Array {
constructor() { super() }
top() { return this[this.length - 1]; }
}
var s = new Stack();
s.push("world");
s.push("hello");
console.log(s.top()); // "hello"
console.log(s.length); // 2
当然,这很有效。 但至少在Traceur中,明确设置长度并不会截断数组。 当通过console.log打印时,输出是对象形式而不是数组形式,这表明有人不会将其视为“真正的”数组。
这是Traceur如何实现内置对象的子类化或ES6限制的问题吗?
在正常情况下,Ecmascript 6中的子类只是语法上的含糖,所以它仍然是Ecmascript 5所做的原型链接。 这意味着Traceur中的扩展类型在大多数情况下与在“真实”ecmascript 6中扩展完全相同。
数组实例很特殊 - ECMAScript 6规范称它们具有异国情调。 他们对属性长度的处理不能通过普通的JavaScript复制。 如果你调用你的构造函数,那么就会创建一个Stack实例,而不是异国情调的对象(异国情调实际上是ES6规范中的官方名称)。
但是不要绝望,解决方案不是由class extends
加糖本身提供,而是通过(重新)引入__proto__
属性。
Ecmascript 6重新引入了可写的__proto__
属性。 它曾经只在Firefox上可用并且已被弃用,但现在又在ES6中完全恢复。 这意味着您可以创建一个真正的数组,然后将其“升级”到您的自定义类。
所以现在你可以做到以下几点:
function Stack(len) {
var inst = new Array(len);
inst.__proto__ = Stack.prototype;
return inst;
}
Stack.prototype = Object.create(Array.prototype);
因此,子类化应该适用于ES6。 你可能不得不手动使用__proto__
技巧,如果他们没有设法使用新的class extends
语法来解决这个过程,而且还有一些未公开的技巧。 您将无法使用Traceur和Typescript之类的转发器在ES5中完成此操作,但您可以使用Firefox(我记得)已经支持__proto__
已经有一段时间在ES5中使用上面的代码了。
问题是你要覆盖构造函数。 如果你删除你的constructor () { super(); }
constructor () { super(); }
,您的示例工作正常,包括截断数组的s.length = 0。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.