super
Baseline
Widely available
This feature is well established and works across many devices and browser versions. Itâs been available across browsers since 2016å¹´3æ.
super ãã¼ã¯ã¼ãã¯ããªãã¸ã§ã¯ããªãã©ã«ãã¯ã©ã¹ã® [[Prototype]] ä¸ã®ããããã£ã«ã¢ã¯ã»ã¹ããããã¹ã¼ãã¼ã¯ã©ã¹ã®ã³ã³ã¹ãã©ã¯ã¿ã¼ãå¼ã³åºãããããããã«ä½¿ç¨ããã¾ãã
super.prop ããã³ super[expr] å¼ã¯ãã¯ã©ã¹ã¨ãªãã¸ã§ã¯ããªãã©ã«ã®ä¸¡æ¹ã«ãããããããã¡ã½ããå®ç¾©ã§æå¹ã§ããsuper(...args) å¼ã¯ã¯ã©ã¹ã³ã³ã¹ãã©ã¯ã¿ã¼å
ã§æå¹ã§ãã
試ãã¦ã¿ã¾ããã
class Foo {
constructor(name) {
this.name = name;
}
getNameSeparator() {
return "-";
}
}
class FooBar extends Foo {
constructor(name, index) {
super(name);
this.index = index;
}
// å¼ã³åºãããªã
getNameSeparator() {
return "/";
}
getFullName() {
return this.name + super.getNameSeparator() + this.index;
}
}
const firstFooBar = new FooBar("foo", 1);
console.log(firstFooBar.name);
// äºæ³ãããçµæ: "foo"
console.log(firstFooBar.getFullName());
// äºæ³ãããçµæ: "foo-1"
æ§æ
super()
super(arg1)
super(arg1, arg2)
super(arg1, arg2, /* â¦, */ argN)
super.propertyOnParent
super[expression]
解説
super ãã¼ã¯ã¼ãã¯ãã颿°å¼ã³åºããï¼super(...args)ï¼ã¨ãããããã£åç
§ãã¨ãã¦ï¼super.prop ããã³ super[expr]ï¼ã® 2 ã¤ã®æ¹æ³ã§ä½¿ç¨ã§ãã¾ãã
ã¡ã¢:
super ã¯ãã¼ã¯ã¼ãã§ããããããã¯ç¹å¥ãªæ§ææ§é ã§ããsuper ã¯ãããã¿ã¤ããªãã¸ã§ã¯ããæã夿°ã§ã¯ããã¾ãããsuper èªä½ãèªã¿åããã¨ãã㨠SyntaxError ãçºçãã¾ãã
const child = {
myParent() {
console.log(super); // SyntaxError: 'super' keyword unexpected here
},
};
æ´¾çã¯ã©ã¹ï¼extends ã使ç¨ï¼ã®ã³ã³ã¹ãã©ã¯ã¿ã¼æ¬ä½ã§ã¯ãsuper ãã¼ã¯ã¼ããã颿°å¼ã³åºããsuper(...args) ã¨ãã¦ç¾ãããã¨ãããã¾ãããã㯠this ãã¼ã¯ã¼ãã使ç¨ããåããã¤ã³ã³ã¹ãã©ã¯ã¿ã¼ãè¿ãåã«å¼ã³åºããªããã°ãªãã¾ãããããã¯è¦ªã¯ã©ã¹ã®ã³ã³ã¹ãã©ã¯ã¿ã¼ãå¼ã³åºãã親ã¯ã©ã¹ã®ãããªãã¯ãã£ã¼ã«ãããã¤ã³ããã¾ãããã®å¾ãæ´¾çã¯ã©ã¹ã®ã³ã³ã¹ãã©ã¯ã¿ã¼ã¯ããã« this ã«ã¢ã¯ã»ã¹ã夿´ãããã¨ãã§ãã¾ãã
ãããããã£åç
§ã ã®å½¢ã§ããªãã¸ã§ã¯ããªãã©ã«ãã¯ã©ã¹ã® [[Prototype]] ã®ã¡ã½ãããããããã£ã«ã¢ã¯ã»ã¹ãããã¨ãã§ãã¾ããã¯ã©ã¹ã®æ¬ä½ã§ã¯ãsuper ã®åç
§ã¯ãå®è¡ã³ã³ããã¹ããã¤ã³ã¹ã¿ã³ã¹ä½æãã¯ã©ã¹åæåãã«ãã£ã¦ãã¹ã¼ãã¼ã¯ã©ã¹ã®ã³ã³ã¹ãã©ã¯ã¿ã¼èªä½ããã³ã³ã¹ãã©ã¯ã¿ã¼ã® prototype ã®ããããã«ãªãã¾ãã詳細ã¯ãä¾ãã®ç¯ãåç
§ãã¦ãã ããã
ãªããsuperã®åç
§ã¯ãã¡ã½ãããå¼ã³åºããããªãã¸ã§ã¯ãã§ã¯ãªããsuperã宣è¨ãããã¯ã©ã¹ã¾ãã¯ãªãã¸ã§ã¯ããªãã©ã«ã«ãã£ã¦æ±ºå®ããã¾ãããããã£ã¦ãã¡ã½ããã®ã¢ã³ãã¤ã³ããåãã¤ã³ããè¡ã£ã¦ãããã®ä¸ã®superã®åç
§ã¯å¤ããã¾ããï¼ãã ããthisã®åç
§ã¯å¤ããã¾ãï¼ãsuperã¯ãã¡ã½ãããã¯ãã¼ã¸ã£ãçæããã¯ã©ã¹ãªãã©ã«ã¾ãã¯ãªãã¸ã§ã¯ããªãã©ã«ã®ã¹ã³ã¼ãå
ã®å¤æ°ã¨è¦ãªãã¾ãï¼ãã ãä¸è¨ã®éããå®éã«ã¯å¤æ°ã§ã¯ãªããã¨ã«æ³¨æãã¦ãã ããï¼ã
super ãä»ãã¦ããããã£ãè¨å®ããã¨ãã¯ããã®ããããã£ã¯ä»£ããã« this ã«è¨å®ããã¾ãã
ä¾
>ã¯ã©ã¹å ã§ã® super ã®ä½¿ç¨
ãã®ã³ã¼ãã¹ããããã¯ãã¯ã©ã¹ã®ä¾ (ã©ã¤ããã¢) ããã¨ã£ã¦ãã¾ããsuper() ãå©ç¨ãããã¨ã§ãRectangle 㨠Square ã®ã³ã³ã¹ãã©ã¯ã¿ã¼ã«å
±éããå¦çãéè¤ãã¦è¨è¿°ããªãããã«ãã¦ãã¾ãã
class Rectangle {
constructor(height, width) {
this.name = "Rectangle";
this.height = height;
this.width = width;
}
sayName() {
console.log(`Hi, I am a ${this.name}.`);
}
get area() {
return this.height * this.width;
}
set area(value) {
this._area = value;
}
}
class Square extends Rectangle {
constructor(length) {
// ããã§ã¯ã親ã¯ã©ã¹ã®ã³ã³ã¹ãã©ã¯ã¿ã¼ãå¼ã³åºããæå®ãããé·ãã
// Rectangle ã® å¹
ã¨é«ãã¨ãã¦æ¸¡ãã¾ãã
super(length, length);
// ã¡ã¢: 'this' ã使ãåã« super() ãå¼ã³åºããªããã°ãªãã¾ããã
// ã§ãªã㨠ReferenceError ãçºçãã¾ãã
this.name = "Square";
}
}
éçã¡ã½ããã§ã® super ã®å¼ã³åºã
super ã¯éçã¡ã½ããã§ãå¼ã³åºããã¨ãã§ãã¾ãã
class Rectangle {
static logNbSides() {
return "I have 4 sides";
}
}
class Square extends Rectangle {
static logDescription() {
return `${super.logNbSides()} which are all equal`;
}
}
Square.logDescription(); // 'I have 4 sides which are all equal'
ã¯ã©ã¹ãã£ã¼ã«ã宣è¨å ã§ super ã«ã¢ã¯ã»ã¹
super ã¯ã¯ã©ã¹ãã£ã¼ã«ãã®åæåä¸ã«ãã¢ã¯ã»ã¹ãããã¨ãã§ãã¾ããsuper ã®åç
§ã¯ãç¾å¨ã®ãã£ã¼ã«ããã¤ã³ã¹ã¿ã³ã¹ãã£ã¼ã«ãã§ããããéçãã£ã¼ã«ãã§ãããã«ãã£ã¦ç°ãªãã¾ãã
class Base {
static baseStaticField = 90;
baseMethod() {
return 10;
}
}
class Extended extends Base {
extendedField = super.baseMethod(); // 10
static extendedStaticField = super.baseStaticField; // 90
}
ãªããã¤ã³ã¹ã¿ã³ã¹ãã£ã¼ã«ãã¯ã³ã³ã¹ãã©ã¯ã¿ã¼ã® prototype ã§ã¯ãªãã¤ã³ã¹ã¿ã³ã¹èªä½ã«è¨å®ããããããsuper ã使ç¨ãã¦ã¹ã¼ãã¼ã¯ã©ã¹ã®ã¤ã³ã¹ã¿ã³ã¹ãã£ã¼ã«ãã«ã¢ã¯ã»ã¹ãããã¨ã¯ã§ãã¾ããã
class Base {
baseField = 10;
}
class Extended extends Base {
extendedField = super.baseField; // undefined
}
ããã§ã¯ãextendedField 㯠10 ã§ã¯ãªã undefined ã§ããbaseField 㯠Base.prototype ã§ã¯ãªããBase ã¤ã³ã¹ã¿ã³ã¹ã®èªåèªèº«ã§å®ç¾©ãããããããã£ã§ããããã§ãããã®ã³ã³ããã¹ãã«ããã super ã¯ãExtended.prototype ã® [[Prototype]] ã§ãã Base.prototype ä¸ã®ããããã£ã®ã¿ãè¦ã¦ããã¾ãã
super ããããã£ãåé¤ããã¨ã¨ã©ã¼ãçºçãã
親ã¯ã©ã¹ã®ããããã£ãåé¤ããããã«ãdelete æ¼ç®å ã super.propãsuper[expr] ã使ããã¨ã¯ã§ãã¾ãããReferenceError ãçºçãã¾ãã
class Base {
foo() {}
}
class Derived extends Base {
delete() {
delete super.foo; // this is bad
}
}
new Derived().delete(); // ReferenceError: invalid delete involving 'super'.
ãªãã¸ã§ã¯ããªãã©ã«å ã§ã® super.prop ã®ä½¿ç¨
super ã¯ãªãã¸ã§ã¯ãåæåå / ãªãã©ã«è¨æ³å
ã§ã使ç¨ã§ãã¾ãããã®ä¾ã§ã¯ã 2 ã¤ã®ãªãã¸ã§ã¯ããã¡ã½ãããå®ç¾©ãã¦ãã¾ãã 2 ã¤ç®ã®ãªãã¸ã§ã¯ãã®ä¸ã§ãsuper ãæåã®ãªãã¸ã§ã¯ãã®ã¡ã½ãããå¼ã³åºãã¦ãã¾ãããã㯠Object.setPrototypeOf() ã®å©ãã§åä½ãããã㯠obj2 ã®ãããã¿ã¤ãã obj1 ã«è¨å®ããã®ã§ãsuper 㯠method1 ã obj1 ä¸ã§è¦ã¤ãããã¨ãã§ãã¾ãã
const obj1 = {
method1() {
console.log("method 1");
},
};
const obj2 = {
method2() {
super.method1();
},
};
Object.setPrototypeOf(obj2, obj1);
obj2.method2(); // "method 1" ãåºå
super.prop ãèªã¿åãã¡ã½ããã¯ãä»ã®ãªãã¸ã§ã¯ãã«ãã¤ã³ãããã¦ãåä½ãå¤ãããªã
super.x ã¸ã®ã¢ã¯ã»ã¹ã¯ Reflect.get(Object.getPrototypeOf(objectLiteral), "x", this) ã®ããã«åä½ãã¾ããããã¯ãããããã£ã常ã«ãªãã¸ã§ã¯ããªãã©ã«/ã¯ã©ã¹å®£è¨ã®ãããã¿ã¤ãä¸ã§æ¤ç´¢ãããã¨ãããã¨ã§ãããã¡ã½ããã®ã¢ã³ãã¤ã³ããåãã¤ã³ããè¡ã£ã¦ã super ã®åç
§ã¯å¤æ´ããã¾ããã
class Base {
baseGetX() {
return 1;
}
}
class Extended extends Base {
getX() {
return super.baseGetX();
}
}
const e = new Extended();
console.log(e.getX()); // 1
const { getX } = e;
console.log(getX()); // 1
ãªãã¸ã§ã¯ããªãã©ã«ã§ãåããã¨ã«ãªãã¾ãã
const parent1 = { prop: 1 };
const parent2 = { prop: 2 };
const child = {
myParent() {
console.log(super.prop);
},
};
Object.setPrototypeOf(child, parent1);
child.myParent(); // "1" ã¨åºå
const myParent = child.myParent;
myParent(); // ããã§ã "1" ã¨åºå
const anotherChild = { __proto__: parent2, myParent };
anotherChild.myParent(); // ããã§ã "1" ã¨åºå
ç¶æ¿ãã§ã¼ã³å
¨ä½ããªã»ãããããã¨ã§ã®ã¿ãsuper ã®åç
§ã夿´ããã¾ãã
class Base {
baseGetX() {
return 1;
}
static staticBaseGetX() {
return 3;
}
}
class AnotherBase {
baseGetX() {
return 2;
}
static staticBaseGetX() {
return 4;
}
}
class Extended extends Base {
getX() {
return super.baseGetX();
}
static staticGetX() {
return super.staticBaseGetX();
}
}
const e = new Extended();
// ã¤ã³ã¹ã¿ã³ã¹ç¶æ¿ã®ãªã»ãã
Object.setPrototypeOf(Extended.prototype, AnotherBase.prototype);
console.log(e.getX()); // ãããã¿ã¤ããã§ã¼ã³ã夿´ãããããã"1" ã§ã¯ãªã "2" ããã°åºå
console.log(Extended.staticGetX()); // ããã§ã "3" ã¨ãã°åºåãã¾ããéçé¨åãã¾ã 夿´ãã¦ããªããã
// éçç¶æ¿ã®ãªã»ãã
Object.setPrototypeOf(Extended, AnotherBase);
console.log(Extended.staticGetX()); // "4" ã¨ãã°åºåãããããã«ãªã
super ããã®ã¡ã½ããå¼ã³åºã
颿°ã¨ã㦠super.prop ãå¼ã³åºããå ´åã prop 颿°å
ã® this å¤ã¯ç¾å¨ã® this ã§ããã super ãæããªãã¸ã§ã¯ãã«ã¯ãªãã¾ãããä¾ãã°ã super.getName() ãå¼ã³åºãã¨ãã³ã¼ãä¸ã¯Base.getName() ã¨åçã«è¦ãã¾ããã"Extended" ãåºåãã¾ãã
class Base {
static getName() {
console.log(this.name);
}
}
class Extended extends Base {
static getName() {
super.getName();
}
}
Extended.getName(); // "Extended" ã¨åºå
ããã¯ç¹ã«ããã©ã¤ãã¼ãéçè¦ç´ ãæä½ããéã«éè¦ã§ãã
super.prop ã«è¨å®ããã¨ã代ããã« this ã®ããããã£ã«è¨å®ããã
super ã®ããããã£ã« super.x = 1 ã®ããã«è¨å®ããã¨ã Reflect.set(Object.getPrototypeOf(objectLiteral), "x", 1, this) ã¨åæ§ã«åä½ãã¾ãããã㯠super ãåã«ããããã¿ã¤ããªãã¸ã§ã¯ãã¸ã®åç
§ãã¨çè§£ããã ãã§ã¯ä¸ååãªã±ã¼ã¹ã®ä¸ã¤ã§ããå®éã«ã¯ this ã®ããããã£ãè¨å®ããããã§ãã
class A {}
class B extends A {
setX() {
super.x = 1;
}
}
const b = new B();
b.setX();
console.log(b); // B { x: 1 }
console.log(Object.hasOwn(b, "x")); // true
super.x = 1 㯠A.prototype ä¸ã® x ã®ããããã£è¨è¿°åãè¦ã¾ããï¼ããã«å®ç¾©ãããã»ãã¿ã¼ãå¼ã³åºãï¼ãthis ã®å¤ã¯ this ï¼ãã®ã³ã³ããã¹ãã§ã¯ bï¼ã«è¨å®ããã¾ããReflect.set ã«ã¯ã target 㨠receiver ãç°ãªãå ´åã®è©³ãã説æãããã¾ãã
ããã¯ãsuper.prop ãåå¾ããã¡ã½ããã¯é常 this ã³ã³ããã¹ãã®å¤æ´ã®å½±é¿ãåããªã䏿¹ã§ãsuper.prop ãè¨å®ããã¡ã½ããã¯å½±é¿ãåããã¨ãããã¨ã§ãã
/* ä¸è¨ã¨åã宣è¨ãåå©ç¨ */
const b2 = new B();
b2.setX.call(null); // TypeError: Cannot assign to read only property 'x' of object 'null'
ãã ããsuper.x = 1 ã¯ä¾ç¶ã¨ãã¦ãããã¿ã¤ããªãã¸ã§ã¯ãã®ããããã£è¨è¿°åãåç
§ããã®ã§ãæ¸ãè¾¼ã¿ä¸å¯ã®ããããã£ã¯ä¸æ¸ãã§ãããã»ãã¿ã¼ãå¼ã³åºããã¾ãã
class X {
constructor() {
// æ¸ãè¾¼ã¿ä¸å¯ã®ããããã£ã使
Object.defineProperty(this, "prop", {
configurable: true,
writable: false,
value: 1,
});
}
}
class Y extends X {
constructor() {
super();
}
foo() {
super.prop = 2; // å¤ã䏿¸ãã§ããªã
}
}
const y = new Y();
y.foo(); // TypeError: "prop" ã¯èªã¿åãå°ç¨
console.log(y.prop); // 1
仿§æ¸
| Specification |
|---|
| ECMAScript® 2027 Language Specification> # sec-super-keyword> |