yoowinsu / blog

issues blog
17 stars 3 forks source link

烦人的强制类型转换 #41

Open yoowinsu opened 7 years ago

yoowinsu commented 7 years ago

本文首发在个人博客yoowin.me

强制类型转换

强制类型转换在流程判断和部分代码不规范的相等运算符中应用比较多,至于为什么说代码不规范,我们后面会说到。 强制类型转换会让一些JavaScript初学者摸不着头脑,但是掌握其中的转换规则之后,就能轻松应对了。

流程判断

if(''){
  console.log('true')  
}
//undefined
if(' '){
  console.log('true')  
}
//true

上面两段代码中返回值一个是undefined,一个是true,看起来会摸不着头脑,两段代码的区别之处在于流程判断时一个是空字符串,一个是空格字符串。 在流程判断中,条件部分的值会被强制转换为布尔值,系统内部会自动调用Boolean函数。 所以上面例子中空字符串会被转化为false,空格字符串被转化为true,下面是转化规则,除了下面几种情况外,都为true: (x代表条件部分的值)

x 转换值
null false
undefined false
''(空字符串) false
0/+0/-0 false
NaN false

另: 下面两种写法,有时也用于将一个表达式转为布尔值。它们内部调用的也是Boolean函数。

x ? true : false
!! x

相等运算符

相等运算符用于比较两个值,然后返回一个布尔值,表示是否相等。 在比较两个值是否相等时,相等运算符(==)比较两个值是否相等,严格相等运算符(===)比较它们是否为“同一个值”。 如果两个值不是同一类型,严格相等运算符(===)直接返回false,而相等运算符(==)会将它们转化成同一个类型,再用严格相等运算符进行比较。

看下面代码:

console.log(''==false)  //true
console.log('0'==false)  //true
console.log(' '==false)  //true
console.log('true'==1)  //false
console.log(true==1)  //true
console.log([]==0)  //true
console.log([1]==true)  //true
console.log([1]=='1')  //true
console.log({valueOf:function(){return 1}}==true)  //true

看到结果是不是一脸懵逼?这里代码看起来违反直觉。 这里强制转换规则确实有点复杂,但是还是有规则可循的:

1.原始类型的数据间的比较

string、boolean、number数据之间比较的话,会先转换成数值类型之后再进行比较。

console.log(''==false)  //true
//等同于Number('') == 0,即0 == 0
console.log('true'==1)  //false
//等同于Number('true') == 1,即NaN == 0
2.原始类型和对象之间的比较

这里的对象指的是广义的对象,包括数组和函数等。 对象与原始类型的值比较时,先转化成原始类型的值,再进行比较。 其中,对象转换为原始类型值转换规则比较复杂,如下:

综上,JavaScript的相等运算符(==)是挺复杂的,也是很容易出错的。 因此为了写出更规范的代码,避免意外,建议大家不要使用相等运算符(==),最好只使用严格相等运算符(===)