Skip to content

JavaScript之坑爹的类型转换 #12

@chenyong9528

Description

@chenyong9528

水一篇文章,谁赞成谁反对?

去看看冴羽的文章不香吗?

JavaScript类型转换

总结一下我认为的重点:

ToPrimitive函数

没错,类型转换时,最让人头秃的就是涉及引用类型时,而引用类型的类型转换就会用到该函数。

我们来实现一下这个函数:

// 该函数用于将引用类型转化为原始值
// 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) // ??

它会经历这样几个步骤:

  1. v1p = ToPrimitive(value1)
  2. v2p = ToPrimitive(value2)
  3. 如果 v1p 是字符串或者 v2p是字符串,那么返回 ToString(v1p) 和 ToString(v2p)的拼接结果
  4. 否则,返回 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"

当然,除此之外还有其他会进行隐式转换的场景,如:- * == 等,可以仔细阅读冴羽同学关于类型转换的博客

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions