0%

JS Symbol.toPrimitive

问题

群友大佐出了一道题

1
2
3
add[1] + 1 // 2
add[1][2][3] + 4 // 10
add[10][-5][3][100] * 2 // 216

解答

他在 stackoverflow 有过提问

https://stackoverflow.com/questions/71688697/how-do-i-achieve-this-curry-function-add-with-square-bracket-notation

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
let add = new Proxy(
{
[Symbol.toPrimitive]() {
return this.value;
},
value: 0
},
{
get(target, key, receiver) {
if(key === Symbol.toPrimitive) {
return target[key];
} else if(key === 'value') {
const sum = target[key];
target[key] = 0;
return sum;
} else if (!isNaN(key)) {
target.value += +key;
}
return add;
},
}
);

console.log(+add[1]);
console.log(+add[1][2][3]);
console.log(+add[10][-5][3][100]);

从上面的代码可以看出,add 是一个 Proxy 对象,它的 value 属性是一个 Symbol.toPrimitive 方法,当 add 被转换为原始值时,会调用 Symbol.toPrimitive 方法,返回 value 属性的值。

而且里面的 + 也比较关键,不然无法在 runtimte 里面调用

知识点

Symbol.toPrimitive

Symbol.toPrimitive 是一个内置的 Symbol 值,它是一个方法,当一个对象转换为原始值时,会调用这个方法,返回原始值。

1
2
3
4
5
6
7
8
9
10
11
12
const obj = {
[Symbol.toPrimitive](hint) {
console.log(hint);
return 1;
}
};

console.log(+obj); // "number"

console.log(`${obj}`); // "string"

console.log(obj + 1); // "default"

具体可以看一下

https://zh.javascript.info/object-toprimitive#symboltoprimitive