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
Object
con unvalue
argumento opcional, se toman los siguientes pasos:
- Si
NewTarget
no esundefined
ni la función activa, entonces
- Regreso ?
OrdinaryCreateFromConstructor(NewTarget, "%ObjectPrototype%")
.- Si el
value
esnull
,undefined
o 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