create - prototype javascript ejemplos
Usando `super()` al extender `Object` (3)
Estoy creando una clase que extiende Object en JavaScript y espero que super() inicialice las claves / valores al construir una nueva instancia de esta clase.
class ExtObject extends Object {
constructor(...args) {
super(...args);
}
}
const obj = new Object({foo:''bar''});
console.log(obj); // { foo: ''bar'' }
const ext = new ExtObject({foo:''bar''});
console.log(ext); // ExtObject {}
console.log(ext.foo); // undefined
¿Por qué no se define foo como ''bar'' en ext en este ejemplo?
EDITAR
Explicación : Usar `super ()` cuando se extiende `Object`
Solución : Usar `super ()` al extender `Object`
En realidad, nadie ha explicado por qué no funciona. Si nos fijamos en la última especificación , la función Object se define de la siguiente manera:
19.1.1.1 Objeto ([valor])
Cuando se llama a la función
Objectcon unvalueargumento opcional, se toman los siguientes pasos:
- Si
NewTargetno esundefinedni la función activa, entonces
- Regreso ?
OrdinaryCreateFromConstructor(NewTarget, "%ObjectPrototype%").- Si el
valueesnull,undefinedo no se proporciona, devuelvaObjectCreate(%ObjectPrototype%).- Regreso !
ToObject(value).
El primer paso es el importante aquí: NewTarget refiere a la función que se NewTarget a new . Así que si haces un new Object , será un Object . Si llamas new ExtObject será ExtObject .
Debido a que ExtObject no es un Object ( "ni la función activa" ), la condición coincide y OrdinaryCreateFromConstructor se evalúa y se devuelve su resultado. Como puede ver, no se hace nada con el value pasado a la función.
value solo se utiliza si ni 1. ni 2. se cumplen. Y si el value es un objeto, simplemente se devuelve como está, no se crea ningún nuevo objeto. Entonces, el new Object(objectValue) es en realidad el mismo que Object(objectValue) :
var foo = {bar: 42};
console.log(new Object(foo) === foo);
console.log(Object(foo) === foo);
En otras palabras: el Object no copia las propiedades del objeto pasado, simplemente devuelve el objeto tal como está. Así que extender Object tampoco copiaría las propiedades.
Esta respuesta funciona solo cuando se usa el transpiler de Babel.
Porque el constructor de Object devuelve valor. Ver spec
15.2.2.1 nuevo objeto ([valor])
Cuando se llama al constructor de objetos sin argumentos o con un valor de argumento, se toman los siguientes pasos:
...
8. Devuelve obj.
class ExtObject extends Object {
constructor(...args) {
return super(...args);
}
}
const obj = new Object({foo:''bar''});
console.log(obj); // { foo: ''bar'' }
const ext = new ExtObject({foo:''bar''});
console.log(ext); // { foo: ''bar'' }
console.log(ext.foo); // bar
Te estás perdiendo el Object.assign
class ExtObject extends Object {
constructor(...args) {
super(...args);
Object.assign(this, ...args);
}
}
const obj = new Object({foo:''bar''});
console.log(obj); // { foo: ''bar'' }
const ext = new ExtObject({foo:''bar''});
console.log(ext); // { foo: ''bar'' }
console.log(ext.foo); // bar