【问题标题】:Why using the unary operator + on an array gives inconsistent results in javascript?为什么在数组上使用一元运算符 + 会在 javascript 中产生不一致的结果?
【发布时间】:2015-07-31 07:07:57
【问题描述】:

当我遇到这种奇怪的行为时,我正在测试将值转换为 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。 有人可以解释这种奇怪的行为或解释这种转换是如何执行的吗?

【问题讨论】:

    标签: javascript arrays


    【解决方案1】:

    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. 如果element0undefinednull,则令R为空字符串;否则,令 RToString(element0)。

    因此,任何包含单个 nullundefined 的数组都将字符串化为空字符串(ToNumber 数字化为 0),而其他值将字符串化为其他字符串(如果字符串是非数字的,它将编号为NaN)。

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

    【讨论】:

    • 哈,你来得比我快。我刚刚完成了GetValue,并且正在通过ToNumber。 ECMA 规范令人惊讶地难以阅读。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-09
    • 2014-06-17
    • 2014-07-25
    • 1970-01-01
    • 2022-01-25
    • 1970-01-01
    相关资源
    最近更新 更多