super() on class that extends
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 es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: super() on class that extends
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=falseevaluate=trueloose=falsespec=falseplayground=falsecode=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 es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: super() on class that extends
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 jacobparker1...@gmail.com 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 a...@rauschma.de rauschma.de ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Syntax sugar for partial application
On 9 April 2015 at 16:11, Jussi Kalliokoski jussi.kallioko...@gmail.com wrote: On Thu, Apr 9, 2015 at 4:04 PM, liorean lior...@gmail.com wrote: Do we really need it? Your «foo(1, ?, 2);» is equivalent to «a=foo(1,a,2)». Your «foo(?, 1, ???);» is equivalent to «(a,...b)=foo(a,1,...b)». Your «foo(1, ???, 2);» is equivalent to «(...a)=foo(...[1,...a,2])». Not exactly. Using the placeholder syntax, `this` remains context dependent, whereas with your examples you get `null` as `this`. No, «this» is lexically bound to be that of the enclosing lexical scope in arrow functions, so it would be whatever that is. But that doesn't really matter as the function call to «foo» doesn't use the «this» of the arrow function. Now, if we were to say your «foo» were actually «foo.bar», and you did the same replacement in the arrow function, the «this» value of the «bar» call would be «foo», so that's pretty much what is wanted as well. The case where this breaks is if you were to replace only the «bar» method with the arrow function, in which case it would use the lexical «this» instead of «foo», but that's obviously not the right transformation to use. This might not seem like such a big deal until you consider it in combination with the proposed bind syntax [1]. Also in your examples, redefining `foo` will lead to different results. The placeholder syntax has a lot more room for optimization in the JIT compiler (the partially applied result is guaranteed to have no side effects for example, so the compiler can create a version of the original function where it can inline the specified arguments; less moving parts, easier to optimize). Yeah, it's susceptible to that problem, yes. Do you want me to fix that for you if you really want it? Your «foo(1, ?, 2);» is equivalent to «((f,a)=f(1,a,2))(foo)». Your «foo(?, 1, ???);» is equivalent to «((f,a,...b)=f(a,1,...b))(foo)». Your «foo(1, ???, 2);» is equivalent to «((f,...a)=f(...[1,...a,2]))(foo)». I guess I didn't think of these cases though, because I only use explicit arguments to my functions these days, I never use the «this» keyword. If I want a function to operate on an object, I pass that object into the function. I also try to not reuse my variables unless they are part of an iteration, in which case they are always local variables that are only handled in the iteration process itself. But that's a side issue, as it's about my code rather than precepts of the language. -- David liorean Andersson ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: super() on class that extends
On 4/10/15, Axel Rauschmayer a...@rauschma.de 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 es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: super() on class that extends
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 dhtmlkitc...@gmail.com wrote: On 4/10/15, Axel Rauschmayer a...@rauschma.de 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 es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: super() on class that extends
No engine has implemented subclassing of `Array`, yet: http://kangax.github.io/compat-table/es6/#Array_is_subclassable 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 dhtmlkitc...@gmail.com wrote: On 4/10/15, Axel Rauschmayer a...@rauschma.de 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 a...@rauschma.de rauschma.de ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: super() on class that extends
No engine has implemented subclassing of `Array`, yet: http://kangax.github.io/compat-table/es6/#Array_is_subclassable http://kangax.github.io/compat-table/es6/#Array_is_subclassable https://github.com/v8/v8-git-mirror/blob/master/test/mjsunit/harmony/classes-subclass-arrays.js https://github.com/v8/v8-git-mirror/blob/master/test/mjsunit/harmony/classes-subclass-arrays.js 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 a...@rauschma.de wrote: No engine has implemented subclassing of `Array`, yet: http://kangax.github.io/compat-table/es6/#Array_is_subclassable 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 dhtmlkitc...@gmail.com mailto:dhtmlkitc...@gmail.com wrote: On 4/10/15, Axel Rauschmayer a...@rauschma.de mailto:a...@rauschma.de 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 http://chordcycles.com/ garretts.github.io personx.tumblr.com -- Dr. Axel Rauschmayer a...@rauschma.de mailto:a...@rauschma.de rauschma.de ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: super() on class that extends
On Apr 10, 2015, at 8:06 PM, Axel Rauschmayer a...@rauschma.de 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 es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: super() on class that extends
On Apr 10, 2015, at 10:29 PM, Axel Rauschmayer a...@rauschma.de wrote: No engine has implemented subclassing of `Array`, yet: http://kangax.github.io/compat-table/es6/#Array_is_subclassable 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 es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss