开发者

Can somebody explain this Javascript method?

开发者 https://www.devze.com 2022-12-19 23:12 出处:网络
Original source: http://twitter.com/tobeytailor/status/8998006366 (x=[].reverse开发者_运维问答)() === window // true

Original source: http://twitter.com/tobeytailor/status/8998006366

(x=[].reverse开发者_运维问答)() === window // true

I've noticed that this behavior affects all the native types. What exactly is happening here?


This is to do with the weird way this binding works in JavaScript.

[].reverse

is the method reverse on an empty list. If you call it, through one of:

[].reverse();
[]['reverse']();
([].reverse)();

then it executes with this bound to the list instance []. But if you detach it:

x= [].reverse;
x();

it executes with no this-binding, so this in the function points to the global (window) object, in one of JavaScript's worst, most misleading design mistakes.

(x=[].reverse)()

Is also doing the detach. The assignment operator returns the same function object it was passed so it looks like it's doing nothing, but it has the side-effect of breaking the limited special case that causes JavaScript to bind this.

So you are saying:

Array.prototype.reverse.call(window)

reverse, like many other Array.prototype methods, is defined by ECMAScript to work on any native sequence-like object. It reverses the items with number-string keys (up to object.length) and returns the object. So it'll return the object that was passed in for any type that has a length property.

window has a length property, which corresponds to window.frames.length, so calling this method with this pointing at window will work and return the window. In theory it may still fail, because:

  1. window is allowed to be a “host object” rather than a “native object”; in this case the guarantees about what you can pass to other prototypes' methods don't necessarily apply; and
  2. if the window actually has frames/iframes, it would try to reverse their order, which wouldn't work because the frame collection is read-only.

However, in current browsers the former case does work and the latter fails silently without an error, so you still get the ===window behaviour and not an Exception.

0

精彩评论

暂无评论...
验证码 换一张
取 消