Why does ++[[]][+[]] == 1?
来源:互联网 发布:nginx 支持pathinfo 编辑:程序博客网 时间:2024/04/27 03:23
Answer by John Resig:
To start, you need to know that JavaScript has type coercion. Numbers can become strings, strings can become numbers, and arrays can become strings.
Thus, for example: [] in a string context becomes "". "" in a number context becomes 0. Thus if we were to do: "" - 1 we'd get the number -1. Additionally if we were to do [] - 1 we'd get -1. ++ is also able to coerce a string into a number.
If ++ is able to turn a string into a number then you're probably wondering why they just don't do ++[] and be done with it (to get 1, that is). The problem is that ++ is attempting to assign that resulting value back somewhere and since [] doesn't exist anywhere yet (it's temporary) it throws an error instead.
We could do something like this:
var a = []; ++a; // 1
But we can't actually assign the result to a variable because we can't use alphanumeric characters. So what's another way in which we can assign the results to a variable? We can stick it into an array. var a = [ [] ]; ++a[ 0 ]; // 1
This also works: ++[ [] ][ 0 ];
Now, we can't use 0 because it's alphanumeric so we swap 0 for +[] (+ turns the string "" into the number 0, [] turns into the string ""). Thus we get the final result: ++[ [] ][ +[] ]
Followed by kangax
The explanation of why ++[] throws error is actually incorrect. This has nothing to do with "existence" of [] (I'm not even sure what existence could mean here). Rather, it's the way ++ operator works.
++ requires its operand to evaluate to a _reference_, not a _value_. If operand evaluates to a value, a ReferenceError is thrown (well, actually it is internal PutValue method that throws error, but that's irrelevant here). Now, if we were to pass reference to ++ operator, it would "work" as expected. E.g.:
++({ x: 1 }).x;
In this case, `({ x: 1 }).x` is a reference, it evaluates to 1, and is then increased by 1 to produce 2 as a resulting value.
When you said "this also works" with `++[ [] ][ 0 ]` example, what happened is that `[ [] ][ 0 ]` evaluated to a reference too, and returned a value of array (inner one). The fact that something like ++[[]][0] "works" should already hint at the fact that "existence" of an object is a bogus reasoning ;)
So what we really need to understand here (besides type coercion) is the notion of references. Literals, for example, always evaluate to values: 1, "foo", true, ({ x: 1 }), and [] are all values. Expressions involving property accessors, on the other hand — foo.bar, [1][0], ({ x: 1 }).x — are all references.
Understanding this distinction can also help explain other aspects of Javascript, such as, say, simple assignments, where left hand operand is constrained by the same rules as ++ operator; it should always evaluate to a reference:
1 = 1; // ReferenceError, LHS operand is not a reference
null = 1; // ReferenceError, LHS operand is not a reference
// but
({ x: 1 }).x = 1; // works as expected, LHS operand is a reference
x = 1; // works as expected, LHS operand is a reference
FWIW, it is the same internal PutValue method that's invoked by `=` operator, and is why assignment to non-reference values result in an error.
Then by John Resig
"This has nothing to do with 'existence' of [] (I'm not even sure what existence could mean here)."
Ah sorry, I was referring to the fact that the array was already created and within another object that we were referencing. But yeah, thanks for your more-in-depth explanation!
- Why does ++[[]][+[]] == 1?
- Why does the C# compiler translate this != comparison as if it were a > comparison?
- Why does App restart?
- Why "RefreshRecord" does not work
- Why does static NSString leak?
- Why Does Gmail Go Down?
- Why is ++[[]][+[]]+[+[]] = “10”-
- Why does microprocessor contain ROM chips?
- Why does sizeof(x++) not increment x?
- Why does Java feel so good
- Why does BitmapSource.Create throw an ArgumentException?
- Why does a virtual function get hidden?
- Why does uploadify.swf request /false URL ?
- Why does my Authorize Attribute not work-
- Why does my Authorize Attribute not work-
- Why does my Authorize Attribute not work-
- Why does my Authorize Attribute not work-
- Why does my Authorize Attribute not work-
- RTSP&RTP
- TCP面试题
- css实现的最简单的标签页
- 复制表,使用 into
- Asp.Net控件Menu 在ie8显示空白的修复
- Why does ++[[]][+[]] == 1?
- ASP.NET刷新页面的六种方法
- Union 中使用Order by
- JSP脚本的9个内置对象(三)——exception对象
- stuts2后台action动态传递参数给前台JSP
- IT服务体系工具支撑
- Android拒绝来电的实现--ITelephony类的反射(结束电话)
- VB.NET多线程开发实例
- Cache Reheating - Not to be Ignored