扩展阵列与ES6类 [英] Extending Array with ES6 classes

查看:95
本文介绍了扩展阵列与ES6类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我听说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中的扩展类型在大多数情况下与实际标签6中的扩展完全相同。



数组实例是特殊的 - ECMAScript 6规范将其称为异常。他们处理属性长度不能通过普通的JavaScript来复制。如果你调用你的构造函数,那么创建一个Stack的实例,而不是一个异乎寻常的对象(异乎寻常的是ES6规范中的官方名称)。



但不要绝望,解决方案不是由$ code> 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 __ 技巧,如果他们没有使用新的类扩展语法还有一些尚未公开的诡计。您将无法使用Traceur和Typescript等透明器在ES5中完成此任务,但您可能可以使用Firefox(尽可能记住)支持的ES5中使用上述代码__proto __ 一段时间。


I have heard that ES6 now finally permits subclassing Array. Here's an example given by

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

Sure, that works. But in Traceur at least, setting the length explicitly does not truncate the array. And when printing via console.log, the output is in object form rather than array form, suggesting that somebody is not looking at it as a "real" array.

Is this a problem with how Traceur implements subclassing built-in objects, or a limitation of ES6?

解决方案

Long answer

In the normal case, the subclassing in Ecmascript 6 is just syntactic sugaring, so it still does the prototypical chaining that Ecmascript 5 does. This means that extending types in Traceur is in most cases exactly the same as extending in "real" ecmascript 6.

Array instances are special – the ECMAScript 6 specification calls them exotic. Their handling of the property length can’t be replicated via normal JavaScript. If you invoke your constructor then an instance of Stack is created, not an exotic object (exotic is actually the official name in the ES6 spec).

But do not despair, the solution is not provided by the class extends sugaring itself, but by the (re)introduction of the __proto__ property.

The solution

Ecmascript 6 reintroduces the writable __proto__ property. It was once only available on Firefox and was deprecated, but is now back in full force in ES6. This means that you can create a real array and then "upgrade" it to your custom class.

So now you can do the following:

function Stack(len) {
    var inst = new Array(len);
    inst.__proto__ = Stack.prototype;
    return inst;
}
Stack.prototype = Object.create(Array.prototype);  

Short answer

So subclassing should work in ES6. You might have to use the __proto__ trick manually if they have not manage to sugar the process using the new class extends syntax with some yet undisclosed trickery. You will not be able to use the transpilers such as Traceur and Typescript to accomplish this in ES5, but you might be able to use the code above in ES5 using Firefox that (as far as I remember) have supported __proto__ for quite some time.

这篇关于扩展阵列与ES6类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆