Abdelellah Dandashi
Abdelellah Dandashi

Reputation: 107

understanding the "this" binding

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?

Upvotes: 3

Views: 247

Answers (3)

chiragrtr
chiragrtr

Reputation: 932

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()

Upvotes: 3

Ali Kleit
Ali Kleit

Reputation: 3649

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

Upvotes: 2

Chase
Chase

Reputation: 3126

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();

Upvotes: 2

Related Questions