functions ecmascript array ecmascript-6 traceur

ecmascript-6 - array - ecmascript 6 class



Extendiendo Array con clases de ES6 (2)

Respuesta larga

En el caso normal, la subclasificación en Ecmascript 6 es solo un azúcar sintáctico, por lo que todavía hace el encadenamiento prototípico que Ecmascript 5 hace. Esto significa que la extensión de tipos en Traceur es en la mayoría de los casos exactamente lo mismo que extender en ecmascript 6 "real".

Las instancias de matriz son especiales: la especificación ECMAScript 6 las llama exóticas. Su manejo de la longitud de la propiedad no puede ser replicado a través de JavaScript normal. Si invocas a tu constructor, se creará una instancia de Stack, no un objeto exótico (en realidad, exótico es el nombre oficial en la especificación ES6).

Pero no se desespere, la solución no es proporcionada por la class extends , sino por la (re) introducción de la propiedad __proto__ .

La solución

Ecmascript 6 reintroduce la propiedad __proto__ escribible. Antes, solo estaba disponible en Firefox y estaba en desuso, pero ahora está de nuevo con ES6. Esto significa que puede crear una matriz real y luego "actualizarla" a su clase personalizada.

Así que ahora puedes hacer lo siguiente:

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

Respuesta corta

Así que la subclasificación debería funcionar en ES6. Es posible que tenga que usar el truco __proto__ manualmente si no han logrado azucarar el proceso utilizando la nueva class extends sintaxis con algunos trucos aún no revelados. No podrá usar los transpilers como Traceur y Typescript para lograr esto en ES5, pero podría usar el código anterior en ES5 con Firefox que (según recuerdo) ha apoyado a __proto__ durante bastante tiempo.

He oído que ES6 ahora finalmente permite subclasificar Array. Aquí hay un ejemplo dado por

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

Claro, eso funciona. Pero al menos en Traceur, establecer la longitud explícitamente no trunca la matriz. Y cuando se imprime a través de console.log, la salida es en forma de objeto en lugar de en forma de matriz, lo que sugiere que alguien no lo está viendo como una matriz "real".

¿Se trata de un problema con la forma en que Traceur implementa la subclasificación de objetos incorporados o una limitación de ES6?


El problema es que estás anulando al constructor. Si eliminas tu constructor () { super(); } constructor () { super(); } , su ejemplo funciona perfectamente, incluyendo s.length = 0 truncando la matriz.