Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can somebody explain this Javascript method?

Tags:

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?

like image 333
user120242 Avatar asked Feb 14 '10 14:02

user120242


People also ask

How do you explain this in JavaScript?

“This” keyword refers to an object that is executing the current piece of code. It references the object that is executing the current function. If the function being referenced is a regular function, “this” references the global object.

What are methods called in JavaScript?

In JavaScript all functions are object methods.

How the call method works JavaScript?

The call() method returns the result of calling the functionName() . By default, the this inside the function is set to the global object i.e., window in the web browsers and global in Node. js. Note that in the strict mode, the this inside the function is set to undefined instead of the global object.

Can you define types in JavaScript?

JavaScript has seven built-in types: null , undefined , boolean , number , string , object , and symbol . They can be identified by the typeof operator. Variables don't have types, but the values in them do. These types define the intrinsic behavior of the values.


1 Answers

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.

like image 165
bobince Avatar answered Sep 17 '22 15:09

bobince