水一篇文章,谁赞成谁反对?
去看看冴羽的文章不香吗?
JavaScript类型转换
总结一下我认为的重点:
没错,类型转换时,最让人头秃的就是涉及引用类型时,而引用类型的类型转换就会用到该函数。
我们来实现一下这个函数:
// 该函数用于将引用类型转化为原始值
// input是需要进行转换的值,type是可选的期望转化为哪种类型的值(如果不传除了Date类型一律视为期望值为Number)
function ToPrimitive(input, type = input instanceof Date ? "String" : "Number") {
// val为基本类型时返回true
const isPrimitive = (val) => val !== Object(val)
if (isPrimitive(input)) return input
const val = input.valueOf()
const str = input.toString()
if (type === "Number") {
if (isPrimitive(val)) return val
if (isPrimitive(str)) return str
} else if (type === "String") {
if (isPrimitive(str)) return str
if (isPrimitive(val)) return val
}
return new TypeError()
}
console.log(ToPrimitive({})) // "[object Object]"
console.log(ToPrimitive([])) // ""
console.log(ToPrimitive([1,2,3])) // "1,2,3"
当我们做加法计算value1 + value2时,会用到上面这个函数,例如:
console.log(null + 1) // ??
它会经历这样几个步骤:
- v1p = ToPrimitive(value1)
- v2p = ToPrimitive(value2)
- 如果 v1p 是字符串或者 v2p是字符串,那么返回 ToString(v1p) 和 ToString(v2p)的拼接结果
- 否则,返回 ToNumber(v1p) 和 ToNumber(v2p)的运算结果
如果用一个函数来实现这四个步骤,如下:
const addition = (v1, v2) => {
const v1p = ToPrimitive(v1)
const v2p = ToPrimitive(v2)
if (typeof v1p === "string" || typeof v2p === "string") {
return String(v1p) + String(v2p)
}
return Number(v1p) + Number(v2p)
}
回到这个例子:
console.log(null + 1)
// 相当于
console.log(addition(null, 1)) // 1
// 试试其他的
console.log(addition([], [])) // ""
console.log(addition({}, [])) // "[object Object]"
console.log(addition(1, true)) // 2
console.log(addition({}, {})) // "[object Object][object Object]"
console.log(addition(new Date(2017, 04, 21), 1)) // "Sun May 21 2017 00:00:00 GMT+0800 (CST)1"
当然,除此之外还有其他会进行隐式转换的场景,如:- * == 等,可以仔细阅读冴羽同学关于类型转换的博客
水一篇文章,谁赞成谁反对?
去看看冴羽的文章不香吗?
JavaScript类型转换
总结一下我认为的重点:
ToPrimitive函数没错,类型转换时,最让人头秃的就是涉及引用类型时,而引用类型的类型转换就会用到该函数。
我们来实现一下这个函数:
当我们做加法计算
value1 + value2时,会用到上面这个函数,例如:它会经历这样几个步骤:
如果用一个函数来实现这四个步骤,如下:
回到这个例子:
当然,除此之外还有其他会进行隐式转换的场景,如:
-*==等,可以仔细阅读冴羽同学关于类型转换的博客