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.