herencia ejemplos create javascript ecmascript-6

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 un value argumento opcional, se toman los siguientes pasos:

  1. Si NewTarget no es undefined ni la función activa, entonces
    1. Regreso ? OrdinaryCreateFromConstructor(NewTarget, "%ObjectPrototype%") .
  2. Si el value es null , undefined o no se proporciona, devuelva ObjectCreate(%ObjectPrototype%) .
  3. 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