자바스크립트/개념

Symbol.species 심볼과 용례

Jake Seo 2022. 12. 24. 08:59

Symbol.species 란?

  • Symbol 오브젝트에서 기본으로 제공하는 Well-known symbol 중 하나이다.
  • 파생된 오브젝트를 만들기 위해 생성자에서 이용하는 Function-valued 프로퍼티를 명시한다.
  • @@species 접근자 프로퍼티는 서브 클래스에서 이를 이용해 기본 생성자를 오버라이드 할 수 있게 해준다.

예제 코드

@@species 오버라이드 해보기

class SubArray extends Array {}

const subArray = new SubArray(1, 2, 3).map((e) => e * 2);
console.log(subArray instanceof SubArray); // true
console.log(subArray instanceof Array); // true

class SubArrayOverride extends Array {
  static get [Symbol.species]() {
    return Array;
  }
}

const subArrayOverride = new SubArrayOverride(1, 2, 3).map((e) => e * 2);
console.log(subArrayOverride instanceof SubArrayOverride); // false
console.log(subArrayOverride instanceof Array); // true

SubArrayOverride 클래스와 같이 @@species 를 오버라이드 해두면, Array 를 상속한 클래스 SubArrayOverride 에서 내장 메서드인 map() 을 사용했을 때의 결과 값이 서브 클래스인 SubArrayOverride 의 인스턴스로 생성 되지 않고 오버라이드한 Array 의 인스턴스로 생성되는 것을 볼 수 있다.

결과가 오버라이드한 Array 의 인스턴스로 생성되는 이유는 map() 내부에서 instance.constructor[Symbol.species] 를 이용하는데, 위 코드에서 이를 접근할 때 Array 를 반환하도록 오버라이드 해놓았기 때문이다.

@@species 를 오버라이드 하지 않으면, 기본 값은 this 로 현재 인스턴스의 생성자가 된다. 이 경우, map() 을 사용했을 때, 위의 SubArray 클래스에서 보이듯 SubArray 인스턴스가 반환된다.

// 설명을 보충하기 위한 가상의 구현 코드
class Array {
  static get [Symbol.species]() {
    return this;
  }
}

레퍼런스

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/species
https://ko.javascript.info/extend-natives
https://hdw0903.github.io/2020/04/06/Symbol%20%ED%94%84%EB%A1%9C%ED%8D%BC%ED%8B%B0%20-ECMAScript/#species_%EA%B0%9C%EB%85%90

반응형