Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JavaScript之坑爹的类型转换 #12

Open
chenyong9528 opened this issue Aug 18, 2020 · 0 comments
Open

JavaScript之坑爹的类型转换 #12

chenyong9528 opened this issue Aug 18, 2020 · 0 comments

Comments

@chenyong9528
Copy link
Owner

chenyong9528 commented Aug 18, 2020

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

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

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"

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant