Well-known Symbols

Well-known Symbols

·

2 min read

Well-known Symbols

Symbol is a built-in object and considered as a primitive type like numbers, booleans, etc.

Everytime we call the Symbol() function, we get a value which is guaranteed to be unique.

let v1 = Symbol();
let v2 = Symbol();

console.log(v1 === v2); // false

There is a special type of symbols call well-known symbols, which is used to customize object behaviors.

Before symbols, if we want customize how to convert object to string, we can define the toString method. Same logic, if we want to customize how to convert object to JSON, we can define the toJSON method. This approach is not ideal, because these method is no different to normal methods. If we want to add more control, we add a new method toXXX, then this method may be the same with your normal methods, then comes the problem.

Now with symbol, because it is guranteed to be unique, so it is suitable for this kind of usage. Now let explore some of them to see how to use them.

Symbol.toStringTag

Customize how to convert object to string.

const obj1 = {
    x: 100,
    y: 200,
}

console.log(String(obj1)) // [object Object]

const obj2 = {
    x: 100,
    y: 200,
    toString() {
        return this.x + "-" + this.y
    }
}

console.log(String(obj2)) // 100-200

const obj3 = {
    x: 100,
    y: 200,
    get [Symbol.toStringTag]() {
        return this.x + "-" + this.y
    }
}

console.log(String(obj3)) // [object 100-200]

Symbol.iterator

Make the object iterable.

let range = {
    from: 1,
    to: 10,

    [Symbol.iterator]() {
        let current = this.from
            , last = this.to;
        return {
            next() {
                return (current <= last)
                    ? { done: false, value: current++ }
                    : { done: true };
            }
        };
    }
};

for (let num of range) {
    console.log(num); // 1, 2, 3, 4, 5, ...
}

Symbol.toPrimitive

Customize how to convert object to primitive values.

let obj = {
    value: 100,
    [Symbol.toPrimitive](hint) {
        if (hint === 'number') return +this.value;
        if (hint === 'string') return "value: " + this.value.toString();
        return this.value.toString();
    }
};
console.log(+obj); // 100
console.log(`${obj}`); // value: 100

Note that there is a hint parameter which is used to know what should the target primitive type is.

Symbol.split

Customize split function.

let obj = {
    [Symbol.split](value) {
        return value.split("_").filter(v => /\d/.test(v))
    }
}

console.log("1_2_3_a_5".split(obj))
// [ '1', '2', '3', '5' ]

Same logic goes with Symbol.match, Symbol.replace, Symbol.search.