Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using `super()` when extending `Object`

I'm creating a class that extends Object in JavaScript and expect super() to initialise the keys/values when constructing a new instance of this class.

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

Why isn't foo defined as 'bar' on ext in this example?

EDIT

Explanation: Using `super()` when extending `Object`

Solution: Using `super()` when extending `Object`

like image 435
Tim Baas Avatar asked Jul 20 '18 09:07

Tim Baas


People also ask

Why do we need super () in an extended class?

The super keyword is used to call the constructor of its parent class to access the parent's properties and methods. Tip: To understand the "inheritance" concept (parent and child classes) better, read our JavaScript Classes Tutorial.

Is super () necessary Java?

However, using super() is not compulsory. Even if super() is not used in the subclass constructor, the compiler implicitly calls the default constructor of the superclass.

Can you use this () and super () both in a constructor?

“this()” and “super()” cannot be used inside the same constructor, as both cannot be executed at once (both cannot be the first statement). “this” can be passed as an argument in the method and constructor calls.

What does super () __ init __ do?

When you initialize a child class in Python, you can call the super(). __init__() method. This initializes the parent class object into the child class. In addition to this, you can add child-specific information to the child object as well.


2 Answers

Nobody has actually explained why it doesn't work. If we look at the latest spec, the Object function is defined as follows:

19.1.1.1 Object ( [ value ] )

When Object function is called with optional argument value, the following steps are taken:

  1. If NewTarget is neither undefined nor the active function, then
    1. Return ? OrdinaryCreateFromConstructor(NewTarget, "%ObjectPrototype%").
  2. If value is null, undefined or not supplied, return ObjectCreate(%ObjectPrototype%).
  3. Return ! ToObject(value).

The first step is the important one here: NewTarget refers to the function that new was called upon. So if you do new Object, it will be Object. If you call new ExtObject it will ExtObject.

Because ExtObject is not Object ("nor the active function"), the condition matches and OrdinaryCreateFromConstructor is evaluated and its result returned. As you can see, nothing is done with the value passed to the function.

value is only used if neither 1. nor 2. are fulfilled. And if value is an object, it is simply returned as is, no new object is created. So, new Object(objectValue) is actually the same as Object(objectValue):

var foo = {bar: 42};  console.log(new Object(foo) === foo);  console.log(Object(foo) === foo);

In other words: Object does not copy the properties of the passed in object, it simply returns the object as is. So extending Object wouldn't copy the properties either.

like image 51
Felix Kling Avatar answered Sep 27 '22 23:09

Felix Kling


You are missing the 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
like image 36
Gildas.Tambo Avatar answered Sep 28 '22 01:09

Gildas.Tambo