super() on class that extends

classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

super() on class that extends

Jacob Parker
Why was this a requirement? I have a class, we’ll call a, which I want to extend from b, but I don’t want to call the constructor. I just want to inherit a few functions from it.
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: super() on class that extends

Kyle Simpson
Neither the base (parent) nor derived (child) class requires a constructor, nor does the child class require a `super()` call. If you omit either constructor, an assumed one is present. However, if you *do* declare a constructor in a derived class, you'll need to call `super()` in it.

So, to the point of your original question, this is totally valid:

```js
class A {
  foo() { console.log("A:foo"); }
}

class B extends A {
  bar() { super.foo(); }
}

var x = new B();

x.bar(); // A:foo
```

See it in action:

http://babeljs.io/repl/#?experimental=false&evaluate=true&loose=false&spec=false&playground=false&code=class%20A%20%7B%0A%20%20foo()%20%7B%20console.log(%22A%3Afoo%22)%3B%20%7D%0A%7D%0A%0Aclass%20B%20extends%20A%20%7B%0A%20%20bar()%20%7B%20super.foo()%3B%20%7D%0A%7D%0A%0Avar%20x%20%3D%20new%20B()%3B%0A%0Ax.bar()%3B



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: super() on class that extends

Axel Rauschmayer
In reply to this post by Jacob Parker
The reason why you need to call the super-constructor from a derived class constructor is due to where ES6 allocates instances – they are allocated by/in the base class (this is necessary so that constructors can be subclassed that have exotic instances, e.g. `Array`):

```js
// Base class
class A {
    // Allocate instance here (done by JS engine)
    constructor() {}
}
// Derived class
class B extends A {
    constructor() {
        // no `this` available, yet
        super(); // receive instance from A
        // can use `this` now
    }
}
// Derived class
class C extends B {
    constructor() {
        // no `this` available, yet
        super(); // receive instance from B
        // can use `this` now
    }
}
```

If you do not call `super()`, you only get into trouble if you access `this` in some manner. Two examples:

```js
// Derived class
class B1 extends A {
    constructor() {
        // No super-constructor call here!
      
        // ReferenceError: no `this` available
        this.foo = 123;
    }
}
// Derived class
class B2 extends A {
    constructor() {
        // No super-constructor call here!
      
        // ReferenceError: implicit return (=access) of `this`
    }
}
```

Therefore, there are two ways to avoid typing super-constructor calls.

First, you can avoid accessing `this` by explicitly returning an object from the derived class constructor. However, this is not what you want, because the object created via `new B()` does not inherit `A`’s methods.

```js
// Base class
class A {
    constructor() {}
}
// Derived class
class B extends A {
    constructor() {
        // No super-constructor call here!
        
        return {}; // must be an object
    }
}
```

Second, you can let JavaScript create default constructors for you:

```js
// Base class
class A {
}
// Derived class
class B extends A {
}
```

This code is equivalent to:

```js
// Base class
class A {
    constructor() {}
}
// Derived class
class B extends A {
    constructor(...args) {
        super(...args);
    }
}
```

On 10 Apr 2015, at 22:51, Jacob Parker <[hidden email]> wrote:

Why was this a requirement? I have a class, we’ll call a, which I want to extend from b, but I don’t want to call the constructor. I just want to inherit a few functions from it.

-- 
Dr. Axel Rauschmayer
[hidden email]
rauschma.de


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: super() on class that extends

Garrett Smith
On 4/10/15, Axel Rauschmayer <[hidden email]> wrote:
> The reason why you need to call the super-constructor from a derived class
> constructor is due to where ES6 allocates instances - they are allocated
> by/in the base class (this is necessary so that constructors can be
> subclassed that have exotic instances, e.g. `Array`):
>
Can you please explain how extending Array works. Also what is the
optional identifier optional for in ClassExpression:

var myArray = (new class B extends Array {
   constructor() {
     super(1,2,3,4,5);
  }
});
alert(myArray.length); // it's 0 in Babel.

--
Garrett
@xkit
ChordCycles.com
garretts.github.io
personx.tumblr.com
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: super() on class that extends

Sebastian McKenzie
Babel is a terrible reference implementation for subclassing since it relies on the engine. See the docs http://babeljs.io/docs/usage/caveats/#classes and https://github.com/babel/babel/issues/1172 for more info. This exact question (super in derived class constructors) was also indirectly bought up recently in this issue: https://github.com/babel/babel/issues/1131




On Fri, Apr 10, 2015 at 6:57 PM, Garrett Smith <[hidden email]> wrote:

On 4/10/15, Axel Rauschmayer <[hidden email]> wrote:
> The reason why you need to call the super-constructor from a derived class
> constructor is due to where ES6 allocates instances - they are allocated
> by/in the base class (this is necessary so that constructors can be
> subclassed that have exotic instances, e.g. `Array`):
>
Can you please explain how extending Array works. Also what is the
optional identifier optional for in ClassExpression:

var myArray = (new class B extends Array {
constructor() {
super(1,2,3,4,5);
}
});
alert(myArray.length); // it's 0 in Babel.

--
Garrett
@xkit
ChordCycles.com
garretts.github.io
personx.tumblr.com
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: super() on class that extends

Axel Rauschmayer
In reply to this post by Garrett Smith
No engine has implemented subclassing of `Array`, yet: http://kangax.github.io/compat-table/es6/#Array_is_subclassable

And, as Sebastian mentioned, you can’t transpile it, because it depends on the cooperation of `Array`: it becomes the base constructor and allocates an exotic array instance (with special handling for `length` etc.) whose prototype is `new.target`.

Axel


On 11 Apr 2015, at 03:57, Garrett Smith <[hidden email]> wrote:

On 4/10/15, Axel Rauschmayer <[hidden email]> wrote:
The reason why you need to call the super-constructor from a derived class
constructor is due to where ES6 allocates instances - they are allocated
by/in the base class (this is necessary so that constructors can be
subclassed that have exotic instances, e.g. `Array`):

Can you please explain how extending Array works. Also what is the
optional identifier optional for in ClassExpression:

var myArray = (new class B extends Array {
  constructor() {
    super(1,2,3,4,5);
 }
});
alert(myArray.length); // it's 0 in Babel.

--
Garrett
@xkit
ChordCycles.com
garretts.github.io
personx.tumblr.com

-- 
Dr. Axel Rauschmayer
[hidden email]
rauschma.de




_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: super() on class that extends

Caitlin Potter
> No engine has implemented subclassing of `Array`, yet: http://kangax.github.io/compat-table/es6/#Array_is_subclassable


Not staged yet, but it is implemented and is very cool. few small pieces missing still

On Apr 10, 2015, at 10:29 PM, Axel Rauschmayer <[hidden email]> wrote:

No engine has implemented subclassing of `Array`, yet: http://kangax.github.io/compat-table/es6/#Array_is_subclassable

And, as Sebastian mentioned, you can’t transpile it, because it depends on the cooperation of `Array`: it becomes the base constructor and allocates an exotic array instance (with special handling for `length` etc.) whose prototype is `new.target`.

Axel


On 11 Apr 2015, at 03:57, Garrett Smith <[hidden email]> wrote:

On 4/10/15, Axel Rauschmayer <[hidden email]> wrote:
The reason why you need to call the super-constructor from a derived class
constructor is due to where ES6 allocates instances - they are allocated
by/in the base class (this is necessary so that constructors can be
subclassed that have exotic instances, e.g. `Array`):

Can you please explain how extending Array works. Also what is the
optional identifier optional for in ClassExpression:

var myArray = (new class B extends Array {
  constructor() {
    super(1,2,3,4,5);
 }
});
alert(myArray.length); // it's 0 in Babel.

--
Garrett
@xkit
ChordCycles.com
garretts.github.io
personx.tumblr.com

-- 
Dr. Axel Rauschmayer
[hidden email]
rauschma.de



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: super() on class that extends

Allen Wirfs-Brock
In reply to this post by Axel Rauschmayer

> On Apr 10, 2015, at 8:06 PM, Axel Rauschmayer <[hidden email]> wrote:
>
> ...
> If you do not call `super()`, you only get into trouble if you access `this` in some manner. Two examples:
>
> ...
>
> Therefore, there are two ways to avoid typing super-constructor calls.
>
> First, you can avoid accessing `this` by explicitly returning an object from the derived class constructor. However, this is not what you want, because the object created via `new B()` does not inherit `A`’s methods.
>
> ```js
> // Base class
> class A {
>     constructor() {}
> }
> // Derived class
> class B extends A {
>     constructor() {
>         // No super-constructor call here!
>        
>         return {}; // must be an object
>     }
> }
> ```
>
> Second, you can let JavaScript create default constructors for you:
>
> ```js
> // Base class
> class A {
> }
> // Derived class
> class B extends A {
> }
> ```
>
> This code is equivalent to:
>
> ```js
> // Base class
> class A {
>     constructor() {}
> }
> // Derived class
> class B extends A {
>     constructor(...args) {
>         super(...args);
>     }
> }
> ```

or third, about the super class to make sure that you correctly initialize the instance to work with inherited methods:

‘’’js
class B extends A {
   constructor(…args) {
         let newObj = Reflect.construct(Object, args, this.target);
         newObj.prop = something;
         return newObj;
   }
}
```

Allen

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: super() on class that extends

Allen Wirfs-Brock
In reply to this post by Axel Rauschmayer

On Apr 10, 2015, at 10:29 PM, Axel Rauschmayer <[hidden email]> wrote:

No engine has implemented subclassing of `Array`, yet: http://kangax.github.io/compat-table/es6/#Array_is_subclassable

And, as Sebastian mentioned, you can’t transpile it, because it depends on the cooperation of `Array`: it becomes the base constructor and allocates an exotic array instance (with special handling for `length` etc.) whose prototype is `new.target`.

note totally true:

```js
class SubArray extends Array {
   constructor(…args) {
      let newObj = new Array(…args);
      newObj.__proto__ = SubArray.prototype;  //or new.target.prototype
      return newObj
    }
    subclassMethiod() {}
}
```

Allen

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: super() on class that extends

Allen Wirfs-Brock

> On Apr 10, 2015, at 10:54 PM, Allen Wirfs-Brock <[hidden email]> wrote:
>>
>
> note totally true:

err, “not"

>
> ```js
> class SubArray extends Array {
>    constructor(…args) {
>       let newObj = new Array(…args);
>       newObj.__proto__ = SubArray.prototype;  //or new.target.prototype
>       return newObj
>     }
>     subclassMethiod() {}
> }
> ```
>
> Allen

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: super() on class that extends

Sébastien Cevey
In reply to this post by Axel Rauschmayer
Does the same apply to subclassing Error?

I've been trying to do that but it doesn't seem to work as expected, in particular passing the message as argument to `super` doesn't seem to do anything.

For example:

``` javascript
class Foo extends Error {
  constructor(message) {
    super(message);
  }
}

var err1 = new Foo("arg");
console.log(err1); // plain Foo object
console.log(err1.message); // "" (empty string!?)

var err2 = new Error("arg");
console.log(err2); // Error object
console.log(err2.message); // "arg"
```

The above is true both with Traceur and Babel.

https://babeljs.io/repl/#?experimental=true&evaluate=true&loose=false&spec=false&code=class%20Foo%20extends%20Error%20%7B%0A%20%20constructor(message)%20%7B%0A%20%20%20%20super(message)%3B%0A%20%20%7D%0A%7D%0A%0Avar%20err1%20%3D%20new%20Foo(%22arg%22)%3B%0Aconsole.log(err1)%3B%20%2F%2F%20plain%20Foo%20object%0Aconsole.log(err1.message)%3B%20%2F%2F%20%22%22%20(empty%20string!%3F)%0A%0Avar%20err2%20%3D%20new%20Error(%22arg%22)%3B%0Aconsole.log(err2)%3B%20%2F%2F%20Error%20object%0Aconsole.log(err2.message)%3B%20%2F%2F%20%22arg%22

On Sat, 11 Apr 2015 at 03:30 Axel Rauschmayer <[hidden email]> wrote:
No engine has implemented subclassing of `Array`, yet: http://kangax.github.io/compat-table/es6/#Array_is_subclassable

And, as Sebastian mentioned, you can’t transpile it, because it depends on the cooperation of `Array`: it becomes the base constructor and allocates an exotic array instance (with special handling for `length` etc.) whose prototype is `new.target`.

Axel


On 11 Apr 2015, at 03:57, Garrett Smith <[hidden email]> wrote:

On 4/10/15, Axel Rauschmayer <[hidden email]> wrote:
The reason why you need to call the super-constructor from a derived class
constructor is due to where ES6 allocates instances - they are allocated
by/in the base class (this is necessary so that constructors can be
subclassed that have exotic instances, e.g. `Array`):

Can you please explain how extending Array works. Also what is the
optional identifier optional for in ClassExpression:

var myArray = (new class B extends Array {
  constructor() {
    super(1,2,3,4,5);
 }
});
alert(myArray.length); // it's 0 in Babel.

--
Garrett
@xkit
ChordCycles.com
garretts.github.io
personx.tumblr.com

-- 
Dr. Axel Rauschmayer
[hidden email]
rauschma.de



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss


Visit theguardian.com. On your mobile and tablet, download the Guardian iPhone and Android apps theguardian.com/guardianapp and our tablet editions theguardian.com/editions.  Save up to 57% by subscribing to the Guardian and Observer - choose the papers you want and get full digital access.  Visit subscribe.theguardian.com

This e-mail and all attachments are confidential and may also be privileged. If you are not the named recipient, please notify the sender and delete the e-mail and all attachments immediately. Do not disclose the contents to another person. You may not use the information for any purpose, or store, or copy, it in any way.  Guardian News & Media Limited is not liable for any computer viruses or other material transmitted with or as part of this e-mail. You should employ virus checking software.
 
Guardian News & Media Limited is a member of Guardian Media Group plc. Registered Office: PO Box 68164, Kings Place, 90 York Way, London, N1P 2AP.  Registered in England Number 908396



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: super() on class that extends

Erik Arvidsson
On Sat, Apr 11, 2015 at 9:09 AM Sébastien Cevey <[hidden email]> wrote:
Does the same apply to subclassing Error?

Subclassing Error works in V8 (Chrome  43).

Caitlin, the only issue I know of in V8 regarding subclassing is subclassing Object and the weird wrapper we create.

class X extends Object {}
let x = new X('hi');
print(x);  // Oops, we created a String wrapper.

This is because we haven't implemented new.target for our self hosted Object function constructor.


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss