Movatterモバイル変換


[0]ホーム

URL:


  1. 개발자를 위한 웹 기술
  2. JavaScript
  3. JavaScript 참고서
  4. 식 및 연산자
  5. super

This page was translated from English by the community.Learn more and join the MDN Web Docs community.

View in EnglishAlways switch to English

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.propsuper[expr] 표현식은클래스객체 리터럴메서드 정의에서 모두 사용할 수 있습니다.super(...args) 표현식은 클래스 생성자에서 유효합니다.

시도해 보기

class Foo {  constructor(name) {    this.name = name;  }  getNameSeparator() {    return "-";  }}class FooBar extends Foo {  constructor(name, index) {    super(name);    this.index = index;  }  // Does not get called  getNameSeparator() {    return "/";  }  getFullName() {    return this.name + super.getNameSeparator() + this.index;  }}const firstFooBar = new FooBar("foo", 1);console.log(firstFooBar.name);// Expected output: "foo"console.log(firstFooBar.getFullName());// Expected output: "foo-1"

구문

js
super([arguments]) // 부모 생성자 호출.super.propertyOnParentsuper[expression]

설명

super 키워드는 "함수 호출"(super(...args)) 또는 "속성 조회"(super.propsuper[expr])의 두 가지 방법으로 사용할 수 있습니다.

참고 :super는 키워드이며 특수한 구문 구조입니다.super는 프로토타입 객체를 가리키는 변수가 아닙니다.super 자체를 읽으려는 시도는SyntaxError입니다.

js
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()RectangleSquare 사이에 공통적인 생성자 부분의 중복을 피하기 위해 호출됩니다.

js
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) {    this.height; // ReferenceError, super가 먼저 호출되어야 합니다!    // 여기서 Rectangle의 너비와 높이에 대해 제공된    // length를 사용하여 부모 클래스의 생성자를 호출합니다.    super(length, length);    // 참고: 파생 클래스에서 'this'를 사용하려면    // 먼저 super()를 호출해야 합니다. 이를 생략하면 참조 오류가 발생합니다.    this.name = "Square";  }}

super를 호출하는 정적 메서드

정적 메서드에서도 super를 호출할 수 있습니다.

js
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의 참조는 현재 필드가 인스턴스 필드인지 정적 필드인지에 따라 다릅니다.

js
class Base {  static baseStaticField = 90;  baseMethod() {    return 10;  }}class Extended extends Base {  extendedField = super.baseMethod(); // 10  static extendedStaticField = super.baseStaticField; // 90}

인스턴스 필드는 생성자의prototype 대신 인스턴스에 설정되므로super를 사용하여 슈퍼클래스의 인스턴스 필드에 접근할 수 없습니다.

js
class Base {  baseField = 10;}class Extended extends Base {  extendedField = super.baseField; // undefined}

여기서baseFieldBase.prototype이 아니라Base 인스턴스의 자체 속성으로 정의되기 때문에 10이 아닌undefined입니다. 이 맥락에서superExtended.prototype의 [[Prototype]]이므로Base.prototype의 속성만 조회할 수 있습니다.

super 속성을 삭제하면 오류가 발생합니다

delete 연산자super.prop 또는super[expr]를 사용하여 부모 클래스의 속성을 삭제할 수 없습니다. 삭제하면ReferenceError가 발생합니다.

js
class Base {  foo() {}}class Derived extends Base {  delete() {    delete super.foo; // 이렇게 하면 안됩니다.  }}new Derived().delete(); // ReferenceError: invalid delete involving 'super'.

객체 리터럴에서 super.prop 사용

super는객체 초기자 표기법에서도 사용할 수 있습니다. 이 예제는 두 객체가 메서드 하나를 정의합니다. 두 번째 객체에서super는 첫 번째 객체의 메서드를 호출합니다. 이는obj2의 프로토타입을obj1로 설정할 수 있는Object.setPrototypeOf()의 도움으로 작동하므로superobj1에서method1을 찾을 수 있습니다.

js
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의 참조는 변경되지 않습니다.

js
class Base {  baseGetX() {    return 1;  }}class Extended extends Base {  getX() {    return super.baseGetX();  }}const e = new Extended();console.log(e.getX()); // 1const { getX } = e;console.log(getX()); // 1

객체 리터럴에서도 동일하게 동작합니다.

js
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의 참조가 변경됩니다.

js
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 값은super가 가리키는 객체가 아니라 현재this입니다. 예를 들어,super.getName() 호출은 코드가Base.getName()과 동일한 것처럼 보이지만"Extended"를 로그합니다.

js
class Base {  static getName() {    console.log(this.name);  }}class Extended extends Base {  static getName() {    super.getName();  }}Extended.getName(); // "Extended" 로그

이는정적 프라이빗 속성과 상호 작용할 때 특히 중요합니다.

super.prop을 설정하면 this 속성이 대신 설정됩니다

super.x = 1과 같은super의 속성을 설정하는 것은Reflect.set(Object.getPrototypeOf(objectLiteral), "x", 1, this)와 같이 동작합니다. 이는super를 단순히 "프로토타입 객체의 참조"로 이해하는 것에 한계가 있는 이유 중 하나입니다. 실제로는this에 대한 속성을 설정하기 때문이죠.

js
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 = 1A.prototype에서x의 속성 설명자를 찾습니다(그리고 거기에 정의된 setter를 호출하죠.). 하지만this 값은 이 맥락에서b로 설정됩니다.targetreceiver가 다른 경우에 대한 자세한 내용은Reflect.set을 참조하세요.

즉,super.propget하는 메서드는 일반적으로 이 맥락의 변경에 영향을 받지 않지만super.propset하는 메서드는 영향을 받을 수 있습니다.

js
/* 위와 동일한 선언 재사용 */const b2 = new B();b2.setX.call(null); // TypeError: Cannot assign to read only property 'x' of object 'null'

그러나super.x = 1은 여전히 프로토타입 객체의 속성 설명자를 참조하므로, 쓸 수 없는 속성을 다시 작성할 수 없으며 setter가 호출됩니다.

js
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" is read-onlyconsole.log(y.prop); // 1

명세서

Specification
ECMAScript® 2026 Language Specification
# sec-super-keyword

브라우저 호환성

같이 보기

Help improve MDN

Learn how to contribute

This page was last modified on byMDN contributors.


[8]ページ先頭

©2009-2025 Movatter.jp