Array[@@species]

Array[@@species] 정적 접근자 속성은 배열 메서드에서 반환 값을 구성하는 데 사용되는 생성자를 반환합니다.

경고: @@species가 존재하면 임의 코드가 실행될 수 있어 보안 취약점이 발생할 수 있습니다. 또한 특정 최적화를 훨씬 더 어렵게 만듭니다. 엔진 구현자는 이 기능을 제거할지 검토하고 있습니다. 가능하면 이 기능에 의존하지 마십시오. toReversed()와 같은 최신 배열 메서드는 @@species를 사용하지 않으며, 항상 새 Array 기반 클래스 인스턴스를 반환합니다.

구문

js
Array[Symbol.species]

반환 값

get @@species가 호출된 생성자(this)의 값입니다. 반환값은 새 배열을 생성하는 배열 메서드에서 반환값을 구성하는 데 사용됩니다.

설명

@@species 접근자 속성은 Array 객체에 대한 기본 생성자를 반환합니다. 하위 클래스 생성자가 이를 재정의하여 생성자 할당을 변경할 수 있습니다. 기본 구현은 기본적으로 다음과 같습니다.

js
// 설명을 위한 가상의 내부 구현
class Array {
  static get [Symbol.species]() {
    return this;
  }
}

이 다형성 구현으로 인해 파생된 하위 클래스의 @@species도 기본적으로 생성자 자체를 반환합니다.

js
class SubArray extends Array {}
SubArray[Symbol.species] === SubArray; // true

기존 배열을 변경하지 않고 새 배열 인스턴스를 반환하는 배열 메서드(예: filter(), map())를 호출하면, 배열의 constructor[@@species]에 접근합니다. 반환된 생성자는 배열 메서드의 반환값을 구성하는 데 사용됩니다. 이렇게 하면 배열 메서드가 배열과 관련이 없는 객체를 반환하도록 만드는 것이 기술적으로 가능합니다.

js
class NotAnArray {
  constructor(length) {
    this.length = length;
  }
}

const arr = [0, 1, 2];
arr.constructor = { [Symbol.species]: NotAnArray };
arr.map((i) => i); // NotAnArray { '0': 0, '1': 1, '2': 2, length: 3 }
arr.filter((i) => i); // NotAnArray { '0': 1, '1': 2, length: 0 }
arr.concat([1, 2]); // NotAnArray { '0': 0, '1': 1, '2': 2, '3': 1, '4': 2, length: 5 }

예제

일반 객체의 species

@@species 속성은 기본 생성자 함수, 즉 ArrayArray 생성자를 반환합니다.

js
Array[Symbol.species]; // [Function: Array]

파생 객체의 species

MyArray와 같은 사용자 정의 Array의 하위 클래스의 인스턴스에서, MyArray의 species는 MyArray 생성자입니다. 그러나 파생 클래스 메서드에서 부모 Array 객체를 반환하려면 이를 덮어쓰는 것이 좋습니다:

js
class MyArray extends Array {
  // MyArray species를 부모 Array 생성자로 재설정
  static get [Symbol.species]() {
    return Array;
  }
}

명세서

Specification
ECMAScript Language Specification
# sec-get-array-@@species

브라우저 호환성

BCD tables only load in the browser

같이 보기