Why an empty Array type-converts to zero? +[](为什么空数组类型转换为零?+[])
问题描述
就在我以为我对 JavaScript 中的类型转换有所了解时,我偶然发现了这个:
just when I thought I understood something about type conversion in JavaScript, I stumbled with this:
+[]; // 0
Number([]); // 0
我的第一个想法是我应该得到 NaN,就像我尝试将空对象转换为数字一样:
My first thought was that I should get NaN, just like if I try to convert an empty object to number:
+{}; // NaN
Number({}); // NaN
我已经搜索了一段时间没有任何成功......
I have been searching about this for a while without any success...
有人能解释一下为什么它被转换为 0 而不是 NaN 吗?
Can somebody explain me why it gets converted to 0 and not to NaN?
这种行为标准吗?
谢谢.
推荐答案
简单来说有两个关键点:
In a brief, there are two key points:
- 空数组的
toString方法返回一个空字符串. - 使用 一元加运算符将空字符串 强制 归零 或作为函数调用的 
Number构造函数(例如+"" === 0;). 
- The 
toStringmethod of an empty array returns an empty string. - An empty string coerces to zero using the unary plus operator or the 
Numberconstructor called as a function (e.g.+"" === 0;). 
例如,我们可以使用一个对象,它定义了一个toString方法,并返回一个空字符串得到一个等价的结果:
For example, we can use an object that defines a toString method, and returns an empty string to have an equivalent result:
var obj = { toString: function () { return "";} };
+obj; //  0
Number(obj); // 0
这种行为是完全标准的.
This behavior is completely standard.
现在是长答案:
一元加运算符和Number 构造函数作为函数调用 在内部使用 ToNumber 抽象操作.
Both, the unary plus operator and the Number constructor called as a function internally use the ToNumber abstract operation.  
ToNumber 将使用另外两个内部操作,ToPrimitive 和 [[DefaultValue]].
ToNumber will use two more internal operations, ToPrimitive and [[DefaultValue]].
当 ToNumber 操作应用于对象时,例如您示例中的空数组,它调用 ToPrimitive 操作,以获取代表原始值并调用 ToNumber 再次使用该值 [1].
When the ToNumber operation is applied to an Object, such the empty array in your example, it calls the ToPrimitive operation, to get a representative primitive value and call ToNumber again using that value [1].
ToPrimitive 操作接收两个参数,一个 Value(这是您的数组对象)和一个提示类型,在本例中为Number",因为我们要进行数字转换.
The ToPrimitive operation receive two arguments, a Value (which is your array object), and a hint type, which in this case is "Number" since we want to make numeric conversion.
ToPrimitive 调用 [[DefaultValue]] 内部方法,同样带有数字"提示类型.
ToPrimitive calls the [[DefaultValue]] internal method, also with a "Number" hint type.
现在,由于我们使用数字"的提示类型,[[DefaultValue]] 内部方法现在将尝试首先调用对象上的 valueOf 方法.
Now, since the hint type we are using "Number", the [[DefaultValue]] internal method now will try to invoke first the valueOf method on the object.
数组对象没有特定的 valueOf 方法,该方法是继承自 Object.prototype.valueOf,并且这个方法简单地返回一个对object本身的引用.
Array objects don't have a specific valueOf method, the method is the one inherited from Object.prototype.valueOf, and this method simply returns a reference to the object itself.
由于 valueOf 方法没有产生 原始值,现在调用 toString 方法,它产生一个空字符串(这是一个原始值),然后 ToNumber 操作将尝试进行 String-Number 转换,最终以 0 [1].
Since the valueOf method didn't result in a primitive value, now the toString method is invoked, and it produces an empty string (which is a primitive value), then the ToNumber operation will try to do String-Number conversion and it finally end up with 0  [1].
但现在您可能想知道,为什么一个空字符串会强制为零?
But now you might wonder, why an empty string coerces to zero?
+""; // 0
ToNumber内部操作应用于 String 类型,即 StringNumericLiteral 产生式.
There is a complete grammar that is used when the ToNumber internal operation is applied to a String type, the StringNumericLiteral production.
NumericLiteral 之间存在一些差异,其中一个差异是:
It has some differences between a NumericLiteral, and one of those differences is that:
为空或仅包含空格的 StringNumericLiteral 将转换为 +0.
A StringNumericLiteral that is empty or contains only white space is converted to +0.
这篇关于为什么空数组类型转换为零?+[]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:为什么空数组类型转换为零?+[]
				
        
 
            
        基础教程推荐
- 每次设置弹出窗口的焦点 2022-01-01
 - 什么是不使用 jQuery 的经验技术原因? 2022-01-01
 - 为什么我在 Vue.js 中得到 ERR_CONNECTION_TIMED_OUT? 2022-01-01
 - 如何使用sencha Touch2在单页中显示列表和其他标签 2022-01-01
 - jQuery File Upload - 如何识别所有文件何时上传 2022-01-01
 - WatchKit 支持 html 吗?有没有像 UIWebview 这样的控制器? 2022-01-01
 - 如何使用 CSS 显示和隐藏 div? 2022-01-01
 - Javascript 在多个元素上单击事件侦听器并获取目标 2022-01-01
 - Node.js 有没有好的索引/搜索引擎? 2022-01-01
 - 如何在特定日期之前获取消息? 2022-01-01
 
    	
    	
    	
    	
    	
    	
    	
    	
						
						
						
						
						
				
				
				
				