So, I understand that I can use super() within the child class to call a function defined on the base class. However, if I want to call that object's super method elsewhere, it bombs
Parent.js
class Parent {
yell() {
console.log('yell')
}
}
Child.js
class Child extends Parent {
shout() {
super.yell() //this works
}
}
Child.super.yell() //this doesnt work
So, I understand that I can use super() within the child class to call a function defined on the base class. However, if I want to call that object's super method elsewhere, it bombs
Parent.js
class Parent {
yell() {
console.log('yell')
}
}
Child.js
class Child extends Parent {
shout() {
super.yell() //this works
}
}
Child.super.yell() //this doesnt work
Share
Improve this question
edited Aug 1, 2015 at 10:41
Leonid Beschastny
51.5k10 gold badges121 silver badges124 bronze badges
asked May 13, 2015 at 15:38
SalarSalar
8619 silver badges13 bronze badges
5
-
7
Child
isn’t an instance ofChild
andsuper
isn’t a property. Do you wantnew Child().yell()
? – Ry- ♦ Commented May 13, 2015 at 15:41 - Whoops, yeah lemme fix that. EDIT: Ok yeah, that worked. Thanks! – Salar Commented May 13, 2015 at 15:54
-
2
super
is specially, pretty much likethis
. It's not a property of the instances. It also doesn't make much sense from an engineering point of view. A caller should not make any assumption about the inheritance chain of an object. It should only be concerned about its interface. – Felix Kling Commented May 13, 2015 at 15:58 - @minitech I'd like to make your answer the accepted answer, but I don't know if that's possible since it's a ment..? – Salar Commented May 13, 2015 at 16:11
- @FelixKling Ahhh wow yeah, makes much more sense now that you put it that way. Thanks – Salar Commented May 13, 2015 at 16:12
2 Answers
Reset to default 4If you want to call a super
method on an instance, either don't implement the method in the child class (which will default to calling the super
method) or call super.methodName()
within the child class method implementation.
Additionally, you are trying to call a method on the class itself rather than an instance, if this is your goal, you need to make the method static
:
class Parent {
static yell() {
console.log('yell')
}
}
class Child extends Parent {
}
Child.yell();
It might help to take a look at the transpiled code that babel outputs:
'use strict';
var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; desc = parent = getter = undefined; _again = false; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
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) subClass.__proto__ = superClass; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
var Parent = (function () {
function Parent() {
_classCallCheck(this, Parent);
}
_createClass(Parent, [{
key: 'yell',
value: function yell() {
console.log('yell');
}
}]);
return Parent;
})();
var Child = (function (_Parent) {
function Child() {
_classCallCheck(this, Child);
if (_Parent != null) {
_Parent.apply(this, arguments);
}
}
_inherits(Child, _Parent);
_createClass(Child, [{
key: 'shout',
value: function shout() {
_get(Object.getPrototypeOf(Child.prototype), 'yell', this).call(this);
}
}]);
return Child;
})(Parent);
There's a few important things here:
- the methods you defined are added to the class's prototype
- the Child prototype is an instance of the Parent class
- calling super grabs the function of the same name from the prototype
So in order to call yell you can do one of a few things:
Object.getPrototypeOf(Object.getPrototypeOf(_Child)).yell.call(_Child)
or
Object.getPrototypeOf(Child.prototype).yell.call(_Child)
or, and I remend this one:
Parent.prototype.yell.call(_Child)