乐趣区

重学JS-隐式强制类型转换

隐式强制类型转换指的是那些隐藏的强制类型转换,副作用也不是很明显,事实上,只要自己觉得不够明显的强制类型转换都可以算作隐式强制类型转换,接下来,此文将会介绍几种常见的隐式类型转换。

加法操作符

转换规则:

  • 如果两个操作数,一个操作数是数字,另一个数是布尔值,那么则将布尔值转换为数字,然后进行加法操作
  • 如果两个操作都是字符串,则将第二个操作数与第一个操作数拼接起来
  • 如果只有一个操作数是字符串,则将另一个操作数转换为字符串,然后再将两个字符串拼接起来

    • 如果另一个操作数是数字、或布尔值,则调用它们的 toString()方法取得对应的字符串值
    • 如果另一个操作数对象,对象 valueOf()方法返回基本值,则调用 valueOf()方法取得返回值,然后再做字符串拼接,否则直接调用 toString()方法取得对应的字符串值

举例:

console.log(1 + true) // 2
console.log('1' + '1') // '11'
console.log(1 + '1') // '11'
console.log('1' + 'true') // '1true'
var a = {valueOf: function() {return 2},
  toString: function() {return 1}
}
var b = {b: 1}
console.log(a + '1') // '21'
console.log(b + '1') // '[object Object]1'

减法操作符

转换规则:

  • 如果有一个操作数字符串、布尔值、null 或者 undefined,则先在后台调用 Number()函数将其转换为数值,如果转换的结果是 NaN,则减法的结果就是 NaN
  • 如果有一个操作数是对象,则调用的 valueOf()方法取得表示该对象的数值,如果得到的结果是 NaN,则减法的结果就是 NaN。如果对象 valueOf()方法返回不是基本值,则调用 toString()方法并将得到的字符串转为数字

举例:

console.log(5 - '1') // 4
console.log(5 - true) // 4
console.log(5 - null) // 5
console.log(5- undefined) // NaN
const c = {valueOf: function() {return '1'}
}
console.log(5 - c) // 4

隐式强制类型转为布尔值

场景:

  • if()语句中的条件判断表达式
  • for()语句中的条件判断表达式
  • while()和 do..while()循环条件中的判断表达式
  • ?: 三元运算中的判断表达式
  • 逻辑元算符 || 和 && 左边的操作数

以上的场景中非布尔值会被隐式的强制转为布尔值,转换规则遵循上篇文章的 ToBoolean 转换规则

举例:

const d = 11
const e = null
let f
const g = f ? d : e
console.log(g) // null
console.log(d && e) // null
console.log(d || e) // 11

相等

相等操作符分为宽松相等 == 和严格相等 ===,这两个都用来判断值是否相等,区别在于在判断两边操作数是否相等时,宽松相等允许进行强制类型转换,而严格相等不允许进行强制类型转换,因此下面只会介绍宽松相等在比较时的强制类型转换

转换规则:

  • 如果有一个操作数是布尔值,则在比较相等性之前先将其转换为数值,false 转为 0true 转为 1
  • 如果一个操作数是字符串,另一个操作数是数字,在比较之前先将字符串转换为数字
  • 如果一个操作数是对象,另一个操作数不是,则调用对象的 valueOf()方法,若不是基本类型值,则调用 toString()方法,用得到的基本类型值按照前面的规则进行比较
  • null 和 undefined 是相等的
  • 要比较相等性之前,不能将 null 和 undefined 转换成其他任何值
  • 如果有一个操作数是 NaN,则相等操作符返回 false, 而不相等返回 true。即使两个操作数都是 NaN,相等操作符也返回 false
  • 如果两个操作数都是对象,则比较它们是不是同一个对象。如果两个操作数都指向同一个对象,则相等操作符返回 true,否则,返回 false

举例:

console.log(null == undefined) // true
console.log('NaN' == NaN) // false
console.log(5 == NaN) // false
console.log(NaN == NaN) // false
console.log(NaN != NaN) // true
console.log(false == 0) // true
console.log(true == 1) // true
console.log(true == 2) // false
console.log(undefined == 0) // false
console.log(null == 0) // false
console.log('5' == 5) // true

比较操作符

比较操作符包括小于 (<)、大于(>)、小于等于(<=)、和大于等于(>=)
转换规则:

  • 如果两个操作数都是字符串,则比较两个字符串的字符编码值
  • 如果一个操作数是数值,则将另一个操作数转换为数值,然后进行数值比较
  • 如果一个操作数是对象,则调用这个对象的 valueOf()方法,若返回值是基本类型,则用得到的结果进行比较,否则调用 toString()方法,用得到的值进行比较
  • 如果一个操作数是布尔值,则先将其转换为数字,然后进行比较

举例:

console.log('11' < 3) // false
console.log(true < 2) // true
const h = {valueOf: function () {return '22'}
}
console.log(h > 1) // true

总结

这篇文章对 JS 中的常见隐式强制类型转换做了一个小结,希望能对大家理解有所帮助。如果有错误或不严谨的地方,欢迎批评指正,如果喜欢,欢迎点赞

退出移动版