JavaScriptのシンボルメソッドhasInstance, isConcatSpreadable, unscopables, species, toPrimitive, toStringTagについて
JavaScriptのシンボルメソッド解説
以下の各シンボルメソッドについて詳しく解説します。目次のリンクからそれぞれのセクションにジャンプできます。
- Symbol.hasInstance
- Symbol.isConcatSpreadable
- Symbol.unscopables
- Symbol.species
- Symbol.toPrimitive
- Symbol.toStringTag
Symbol.hasInstance
Symbol.hasInstance
は、instanceof
演算子が使用されたときにカスタムの判定ロジックを提供するために利用されます。
デフォルトでは、オブジェクトのプロトタイプチェーンを基にinstanceof
が動作しますが、このシンボルを使用すると柔軟な判定が可能になります。
例
class CustomClass {
static [Symbol.hasInstance](instance) {
return instance.customProperty === true;
}
}
const obj1 = { customProperty: true };
const obj2 = { customProperty: false };
console.log(obj1 instanceof CustomClass); // true
console.log(obj2 instanceof CustomClass); // false
Symbol.isConcatSpreadable
Symbol.isConcatSpreadable
は、配列や配列に似たオブジェクトがArray.prototype.concat
メソッドで展開されるかどうかを制御します。
デフォルトでは、配列は展開されますが、オブジェクトは展開されません。このシンボルを使うことで、その挙動を上書きできます。
例
let arrayLike = { 0: 'a', 1: 'b', length: 2, [Symbol.isConcatSpreadable]: true };
let result = [].concat(arrayLike);
console.log(result); // ['a', 'b']
let array = ['x', 'y'];
array[Symbol.isConcatSpreadable] = false;
let result2 = [].concat(array);
console.log(result2); // [['x', 'y']]
Symbol.unscopables
Symbol.unscopables
は、with
文内で特定のプロパティをスコープから除外するために使用されます。デフォルトでArray
オブジェクトにはこのシンボルが設定されています。
例
let obj = { a: 1, b: 2, [Symbol.unscopables]: { b: true } };
with (obj) {
console.log(a); // 1
console.log(typeof b); // 'undefined'
}
Symbol.species
Symbol.species
は、派生オブジェクトがどのクラスのインスタンスを返すかを制御するために使用されます。
通常は継承されたクラスのコンストラクタが返されますが、このシンボルを使うとカスタマイズ可能です。
例
class MyArray extends Array {
static get [Symbol.species]() {
return Array;
}
}
let myArray = new MyArray(1, 2, 3);
let filtered = myArray.filter(x => x > 1);
console.log(filtered instanceof MyArray); // false
console.log(filtered instanceof Array); // true
Symbol.toPrimitive
Symbol.toPrimitive
は、オブジェクトがプリミティブ値に変換される際のカスタム動作を提供します。このシンボルを実装すると、Number()
やString()
などでの変換挙動を制御できます。
例
let obj = {
[Symbol.toPrimitive](hint) {
if (hint === 'number') {
return 42;
} else if (hint === 'string') {
return 'Hello';
} else {
return null;
}
}
};
console.log(+obj); // 42
console.log(`${obj}`); // "Hello"
console.log(obj + ''); // "null"
Symbol.toStringTag
Symbol.toStringTag
は、オブジェクトのObject.prototype.toString
メソッドで返される文字列をカスタマイズするために使用されます。
通常は[object Object]
などが返されますが、このシンボルを設定することで変更可能です。
例
let customObj = {
[Symbol.toStringTag]: 'CustomObject'
};
console.log(Object.prototype.toString.call(customObj)); // "[object CustomObject]"
class MyClass {
get [Symbol.toStringTag]() {
return 'MyClass';
}
}
let instance = new MyClass();
console.log(Object.prototype.toString.call(instance)); // "[object MyClass]"
これらのシンボルメソッドは、JavaScriptの柔軟性を活かし、カスタムの振る舞いを実現するために非常に強力なツールです。必要に応じて適切に活用しましょう。