为什么JavaScript 2中的2 == [2]?
我最近在JavaScript中发现了2 == [2]
。 事实证明,这个怪癖有一些有趣的结果:
var a = [0, 1, 2, 3];
a[[2]] === a[2]; // this is true
同样,以下工作:
var a = { "abc" : 1 };
a[["abc"]] === a["abc"]; // this is also true
即使是陌生人,这也适用:
[[[[[[[2]]]]]]] == 2; // this is true too! WTF?
这些行为在所有浏览器中看起来都一致。
任何想法为什么这是一种语言功能?
这个“特征”会带来更多疯狂的后果:
[0] == false // true
if ([0]) { /* executes */ } // [0] is both true and false!
var a = [0];
a == a // true
a == !a // also true, WTF?
这些例子是由jimbojw http://jimbojw.com名声以及walkingeyerobot发现的。
您可以在ECMA-spec中查找比较算法(ECMA-262的相关章节,第3版,针对您的问题:11.9.3,9.1,8.6.2.6)。
如果将涉及的抽象算法翻译回JS,评估2 == [2]
时会发生什么基本上是这样的:
2 === Number([2].valueOf().toString())
其中数组的valueOf()
返回数组本身,而单元素数组的字符串表示形式是单个元素的字符串表示形式。
这也解释了第三个例子,因为[[[[[[[2]]]]]]].toString()
仍然只是字符串2
。
正如你所看到的,涉及到很多幕后魔法,这就是为什么我通常只使用严格的等号运算符===
。
第一个和第二个例子更容易遵循,因为属性名称总是字符串,所以
a[[2]]
相当于
a[[2].toString()]
这只是
a["2"]
请记住,在任何数组魔法发生之前,即使数字键都被视为属性名称(即字符串)。
这是因为==
运算符的隐式类型转换。
与数字进行比较时,[2]被转换为数字2。 试试[2]上的一元+
运算符。
> +[2]
2
var a = [0, 1, 2, 3];
a[[2]] === a[2]; // this is true
在等式的右边,我们有a [2],它返回值为2的数字类型。在左边,我们首先创建一个单个对象为2的新数组。然后我们调用一个[(数组在这里)]。 我不确定这是评估字符串还是数字。 2或“2”。 让我们先拿起字符串案例。 我相信[“2”]会创建一个新变量并返回null。 null!== 2.所以让我们假设它实际上是隐式转换为数字。 a [2]会返回2. 2和2匹配类型(所以===作品)和值。 我认为这是隐式地将数组转换为数字,因为[value]需要一个字符串或数字。 它看起来像数字具有更高的优先级。
在附注中,我想知道谁决定了优先顺序。 是因为[2]有一个数字,因为它是第一个项目,所以它转换为数字? 或者,当将数组传递给[数组]时,它会尝试将数组先转换为数字,然后再转换为字符串。 谁知道?
var a = { "abc" : 1 };
a[["abc"]] === a["abc"];
在这个例子中,你正在创建一个名为a的对象,其成员名为abc。 等式的右边非常简单; 它相当于a.abc。 这将返回1.左侧首先创建一个[“abc”]的文字数组。 然后通过传入新创建的数组来搜索对象上的变量。 由于这需要一个字符串,它将数组转换为一个字符串。 现在评估为[“abc”],它等于1. 1和1是相同的类型(这就是为什么===起作用)和相等的值。
[[[[[[[2]]]]]]] == 2;
这只是一个隐式转换。 ===在这种情况下不起作用,因为类型不匹配。
链接地址: http://www.djcxy.com/p/12533.html上一篇: Why does 2 == [2] in JavaScript?
下一篇: How do I work around JavaScript's parseInt octal behavior?