2

Im reading "Eloquent Javascript" book and I'm in the chapter "The secret life of objects". And the author says:

"since each function has it's own bindings, whose value depends on they way it is called, you cannot refer to the this of the wrapping scope in a regular function defined with the function keyword.

i did not understand what does he mean by "wrapping scope", can you please explain and provide a simple example?

  • the code between `{}` is a wrapping scope of a `function` – El. May 23 '20 at 20:34
  • You need to understand [what scope is](https://stackoverflow.com/questions/41385835/invocation-context-and-execution-context-in-javascript-are-we-talking-of-th/41386097#41386097). – Scott Marcus May 23 '20 at 20:35
  • Does this answer your question? [How does the "this" keyword work?](https://stackoverflow.com/questions/3127429/how-does-the-this-keyword-work) – Orkhan Alikhanov May 23 '20 at 20:45

3 Answers3

3

Wrapping scope of your function would be the scope where the function is defined. e.g.

function outer() {
    var outerThis = this;
    return function inner() {
        console.log(outerThis, this);
    }
}

Here, inner function has wrapping scope = scope of outer. And, the inner function doesn't have access to the outer's this which is why we need to store it in a variable outerThis if we want to use it.

var innerFunction = outer.call({});
innerFunction();

If you do above on chrome console, This will print:

{},        // Caller of outer() (it was bound)
Window     // Caller of inner()
chiragrtr
  • 832
  • 4
  • 6
2

Here is an example of how the use of "function" keyword will produce a function that does not have the same meaning to "this" as the containing scope has. You can overcome this by using an arrow function.

See also: https://medium.com/better-programming/difference-between-regular-functions-and-arrow-functions-f65639aba256

const container = {
  name: "Bob",
  sayName: function() {
    console.log('say name root:', this.name);
    const nestedWithFunctionKeyword = function() {
      // Notice here that introducing "function" ruins the "this" reference. It no longer is referring to "container".
      console.log('say name function:', this.name);
    };
    
    nestedWithFunctionKeyword();
    
    // But we can re-bind "this" if we want.
    nestedWithFunctionKeyword.call(this);
    
    const nestedWithArrowSyntax = () => {
      console.log('say name with arrow:', this.name);
    };
    
    nestedWithArrowSyntax();
  },
};

container.sayName();

console.log('-----------------');

// Now lets look how how "the way you call the function" matters. Here we do not call the function within the context of "container" anymore, so the results change.
const sayNameRef = container.sayName;
sayNameRef();
Chase
  • 2,833
  • 10
  • 12
2

this keyword refers to the object it belongs to, for example:

function diner(order) {
    
    this.order = order;
    this.table = 'TABLE 1';

    this.eatHere = eatHere
    this.goOutside = goOutside

    function eatHere() {
    
        // adding () instead of a function
        // will use the scope of the object it self
        setTimeout(() => {
            console.log(`EAT HERE: eating ${this.order} at ${this.table}`);
            
        }, 200);
    }
    function goOutside() {
    
        // adding a new function scope inside the function
        // will go outside the current object's scope
        setTimeout(function () {
            console.log(`EAT OUTSIDE: eating ${this.order} at ${this.table}`);
            
        }, 200);
    }
}

let obj = new diner("soup");

obj.eatHere(); // this order will be defined
obj.goOutside(); // this order will be undefined
Ali Kleit
  • 1,677
  • 2
  • 15
  • 26