// It's an error to have a non-constructor as your heritage assertThrowsInstanceOf(() => eval(`class a extends Math.sin { constructor() { } }`), TypeError); assertThrowsInstanceOf(() => eval(`(class a extends Math.sin { constructor() { } })`), TypeError); // Unless it's null, in which case it works like a normal class, except that // the prototype object does not inherit from Object.prototype. class basic { constructor() { } } class nullExtends extends null { constructor() { } } var nullExtendsExpr = class extends null { constructor() { } }; assertEq(Object.getPrototypeOf(basic), Function.prototype); assertEq(Object.getPrototypeOf(basic.prototype), Object.prototype); for (let extension of [nullExtends, nullExtendsExpr]) { assertEq(Object.getPrototypeOf(extension), Function.prototype); assertEq(Object.getPrototypeOf(extension.prototype), null); } var baseMethodCalled; var staticMethodCalled; var overrideCalled; class base { constructor() { }; method() { baseMethodCalled = true; } static staticMethod() { staticMethodCalled = true; } override() { overrideCalled = "base" } } class derived extends base { constructor() { super(); }; override() { overrideCalled = "derived"; } } var derivedExpr = class extends base { constructor() { super(); }; override() { overrideCalled = "derived"; } }; // Make sure we get the right object layouts. for (let extension of [derived, derivedExpr]) { baseMethodCalled = false; staticMethodCalled = false; overrideCalled = ""; // Make sure we get the right object layouts. assertEq(Object.getPrototypeOf(extension), base); assertEq(Object.getPrototypeOf(extension.prototype), base.prototype); // We do inherit the methods, right? (new extension()).method(); assertEq(baseMethodCalled, true); // But we can still override them? (new extension()).override(); assertEq(overrideCalled, "derived"); // What about the statics? extension.staticMethod(); assertEq(staticMethodCalled, true); } // Gotta extend an object, or null. function nope() { class Foo extends "Bar" { constructor() { } } } function nopeExpr() { (class extends "Bar" { constructor() { } }); } assertThrowsInstanceOf(nope, TypeError); assertThrowsInstanceOf(nopeExpr, TypeError); // The .prototype of the extension must be an object, or null. nope.prototype = "not really, no"; function stillNo() { class Foo extends nope { constructor() { } } } function stillNoExpr() { (class extends nope { constructor() { } }); } assertThrowsInstanceOf(stillNo, TypeError); assertThrowsInstanceOf(stillNoExpr, TypeError); if (typeof reportCompare === "function") reportCompare(0, 0, "OK");