Appearance
运算符
大数运算
js
const START = 2 ^ 53
const END = START + 100
for (let i = START; i < END; i++) {
console.log(i)
}
上述会循环多少次?
无法预测,或者不好计算
因为 JS 是使用的双精度浮点数存储数字的,其最大值就是 2 ^ 53 - 1, 如果超过这个就会产生精度丢失,从而不好判断究竟是多少
a == 1 && a == 2 && a == 3
如何使上述表达式成立
- 借助于 toString
js
const a = {
n: 1,
toString: function () {
return a.n++
},
}
if (a == 1 && a == 2 && a == 3) {
console.log("true")
}
对象有 toString() 和 valueOf()两个方法,
toString()将该对象的原始值以字符串的形式返回,valueOf()返回最适合该对象的原始值
这两个方法一般是交由 JS 去隐式调用,以满足不同的运算情况。
在数值运算里,会优先调用 valueOf(),在字符串运算里,会优先调用 toString()。
用运算符对对象进行转换的时候 valueOf()的优先级高于 toString()
对对象进行强字符串转换时会优先调用 toString()
toString()方法不能对 null 和 undefined 进行字符串转换,可以用 String()方法代替
借助于 Symbol.toPrimitive
js
const a = {
n: 1,
[Symbol.toPrimitive]() {
return this.n++
},
}
if (a == 1 && a == 2 && a == 3) {
console.log("true")
}
Symbol.toPrimitive 是一个内置的 Symbol 值,它是作为对象的函数值属性存在的,当一个对象转换为对应的原始值时,会调用此函数。
Symbol.toPrimitive 属性可以将对象转换为相应的原始值。很多内置操作都会尝试将值将对象转换为原始值,包括字符串、数值和未指定的原始类型。
Symbol.toPrimitive的优先级高于 toString- 相似的还有
Symbol.iterator实现对象的遍历操作
对象属性名
js
const a = {}
const b = { key: 123 }
const c = { key: 456 }
a[b] = 123
a[c] = 456
console.log(a[b])结果是什么
456
在 JS 中获取对象属性值的时候是默认转换成字符串类型的,所以上述问题 a[b] = 123的时候其实际结果为
a[ b.toString() ] = 啥
如果没有重写 b 的 toString()方法,那么其默认值就是 "[Object String]" 字符串 (这也是我们判断数据类型用的核心方法),所以对于上述问题其核心就是 a["[Object String]"] = 123 ; a["[Object String]"] = 123 ; console.log(a["[Object String]"]) ,结果就是a[c]覆盖了a[b]为456
js
const a = {}
a["1"] = 123
a[1] = 456
console.log(a["1"]) //结果为 456