What is and how does the context in Javascript work?

15

Essential part of Javascript, every function in Javascript has context, how does it work, how does it manipulate it, and what changes in the strict mode ( 'use strict' )?

    
asked by anonymous 11.03.2014 / 23:53

1 answer

21

In JavaScript, the execution context of a piece of code - which defines what its lexical scope, among other things - has a property called ThisBinding , which can be accessed at any time through the keyword this . This property - present even when you are not inside a function and / or this function is not an object's method - is popularly known as the context [function].

Initially (ie at "top-level") this corresponds to a reference to the global object . In browsers, it is called window , and is self-referencing . When interpreting a code through eval , it is kept as is. When calling a function, it changes as follows:

  • If this function is called in the form of a method (i.e. name, period, name, parentheses) this becomes a reference to the object that was "target" of the call:

    obj.f(); // Dentro de "f", this === obj
    

    As pointed out by @bfavaretto, if the object is a primitive type (as a number), then the this can suffer coercion for an object . This does not occur in strict mode.

    Number.prototype.foo = function() { 
        console.log(typeof this);
    }
    10.0.foo(); // "number" no modo estrito, "object" caso contrário
    
  • If you use one of the methods call , apply or bind , this is explicitly assigned:

    f.call(obj, foo, bar); // Dentro de "f", this === obj
    f.apply(obj, [foo]);   // idem
    f.bind(obj);           // idem
    

    This is worth even though the function has been referenced in the form of an "object method":

    obj.f.call(bar); // Dentro de "f", this === bar
    

    In strict mode, what is passed as the first parameter will be this , without modification. Otherwise, there may be the same coercion as the previously mentioned object or, if the value passed as a parameter is null or undefined , this returns to the global object:

    f.call(20);   // 20 no modo estrito, Number(20) caso contrário
    f.call(null); // null no modo estrito, window caso contrário
    f.call();     // undefined no modo estrito, window caso contrário
    
  • If the function is called in the "normal" form (i.e. name, parentheses), then of the two one:

    • In strict mode, this will be undefined :

      "use strict";
      f(); // Dentro de "f", this === undefined
      
    • In all other cases, this is again a reference to the global object:

      f(); // Dentro de "f", this === window
      

      ... which often causes confusion:

      var obj = {
          f:function() {
              function g() {
                  console.log(this); // this não é obj, e sim window ou undefined
                                     // (conforme o modo, estrito ou não)
              }
              g(); // Espera-se que imprima "obj", mas não é o que ocorre
          }
      }
      

The main way of manipulating the context, as we have seen, is through the methods call , apply and bind . The latter creates a "view" of the original function where this is "tied" to the parameter used, and can not be modified (a kind of #, also allowing you to fix the first N arguments) - not even by other methods:

function f() {
    console.log(this);
}
var x = f.bind(10); // this está amarrado a 10
x.call(20);         // não muda o this, ainda imprime 10

As for the strict mode, the main impact in this context is the one exposed above - where this does not refer to the global object when omitted (i.e. when not explicitly assigned). This has an impact on security because it facilitates sandboxing of unreliable code. There are many other impacts that the strict mode exerts on execution contexts and scope, but nothing that affects the operation of this (even eval continues behaving in the same way in both modes).

jsFiddle with all the above examples .

    
12.03.2014 / 02:09