1

It is said that the ES6 class keyword is just syntactic sugar for Javascript's prototype-based inheritance system. This is obvious to see with one exception: the extends keyword. For example:

class Foo {
    constructor(){
        this.sayHello = () => console.log('Hello')
    }
}

class Bar extends Foo {
    constructor(){
        super(); 
        this.sayGoodbye = () => console.log('Goodbye');
    }
}

If class is just syntactic sugar, what is happening under the hood here? Is there a standard < ES6 design pattern that simulates class inheritance being invoked, or is this some new functionality?

dcastrodale
  • 87
  • 1
  • 4

2 Answers2

1

Is there a standard < ES6 design pattern that simulates class inheritance being invoked?

JavaScript has a prototype inheritance model, which is also what you get with the class keyword. Your code is approximately equivalent to:

function Foo () {
    this.sayHello = () => console.log('Hello')
}

function Bar () {
    // super();
    Foo.call( this );

    this.sayGoodbye = () => console.log('Goodbye');
}

// extends
Bar.prototype = Object.create( Foo.prototype );
Bar.prototype.constructor = Bar;
Paul
  • 139,544
  • 27
  • 275
  • 264
-1

what is happening under the hood here?

That's an implementation detail of the JS engine.

Is there a standard < ES6 design pattern that simulates class inheritance being invoked

"Standard" is probably going too far, but Babel is a well known transpiler that can convert ES6 to ES5.

It gives this:

'use strict';

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var Foo = function Foo() {
    _classCallCheck(this, Foo);

    this.sayHello = function () {
        return console.log('Hello');
    };
};

var Bar = function (_Foo) {
    _inherits(Bar, _Foo);

    function Bar() {
        _classCallCheck(this, Bar);

        var _this = _possibleConstructorReturn(this, (Bar.__proto__ || Object.getPrototypeOf(Bar)).call(this));

        _this.sayGoodbye = function () {
            return console.log('Goodbye');
        };
        return _this;
    }

    return Bar;
}(Foo);
Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335