JavaScriptのシンボルメソッドhasInstance, isConcatSpreadable, unscopables, species, toPrimitive, toStringTagについて

JavaScriptのシンボルメソッドhasInstance, isConcatSpreadable, unscopables, species, toPrimitive, toStringTagについて

JavaScriptのシンボルメソッドについて

JavaScriptのシンボルメソッド解説

以下の各シンボルメソッドについて詳しく解説します。目次のリンクからそれぞれのセクションにジャンプできます。

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の柔軟性を活かし、カスタムの振る舞いを実現するために非常に強力なツールです。必要に応じて適切に活用しましょう。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です