为什么在数组上使用一元运算符+会在javascript中产生不一致的结果?

时间:2015-05-19 12:39:35

标签: javascript arrays

我正在做一些测试,在javascript中将值转换为整数,并在遇到这种奇怪的行为时在控制台中打印输出。

console.log(+[]) ==> 0
console.log(+[123]) ==> 123
console.log(+['123']) ==> 123
console.log(+[123, 456]) ==> NaN
console.log(+['123asdf']) ==> NaN

我认为这些值是使用parseInt转换的,但事实证明它并非如此,所以我转到了javascript转换表http://www.w3schools.com/js/js_type_conversion.asp

这可以让我更好地了解转化的执行方式。根据此表

[] => 0
[20] => 20
[10,20] => NaN
["twenty"] =>NaN
["ten","twenty"] => NaN

所以他们显然采用数组的第一个值并使用指定的规则进行转换。 parseInt的规则不适用。

我测试得出这个结论。您可以将所有内容嵌套,它会给您相同的结果。

console.log(+[[[[[[[[[[[10]]]]]]]]]]]) => 10

那么我想,如果那是

那就好了
console.log(+[undefined]) will return NaN
console.log(+[null]) will return 0
console.log(+[false]) will return 0

这些是从javascript转换表到整数的预期值,但结果是

console.log(+[undefined]) => 0
console.log(+[null]) => 0
console.log(+[false]) => NaN

最后一个是最奇怪的,因为false被转换为0,而不是NaN。 有人可以解释这种奇怪的行为或解释如何进行这种转换吗?

1 个答案:

答案 0 :(得分:6)

Unary + operator内部使用 ToNumber 抽象操作。

ToNumber abstract operation应用于对象时,调用对象的toString方法(通过[[DefaultValue]] internal method),然后重新应用 ToNumber 操作在结果字符串表示。

这里有趣的是Array的toString方法。请注意,[false].toString()[undefined].toString()[null].toString()完全不同。当我们检查Array.prototype.toString的规范时,我们会在内部看到它使用Array.prototype.joinjoin算法的第8步说:

  
      
  1. 如果 element0 undefinednull,请将 R 设为空字符串;否则,让 R ToString element0 )。
  2.   

因此,包含单个nullundefined的任何数组都会串行化为空字符串( ToNumber number-ifies to 0),而其他值将字符串化为其他字符串(如果该字符串为非数字字符串,则将其编号为NaN。)

+[undefined]+""相同,而+[false]+"false"相同。