0

Can someone explain to me why the second function call returns undefined? I see no reason for that. The reference of the object method is stored in a variable, so it should be printed out. Why the result is undefined? The first function call is successful and the only difference is that the second one is stored in a variable.

const module = {
  x: 42,
  getX: function() {
    return this.x;
  }
};

//1 - returns 42
console.log(module.getX());

//2 - returns undefined
const unboundGetX = module.getX;
console.log(unboundGetX());

Miloš Leng
  • 61
  • 1
  • 8

1 Answers1

1

Because unboundGetX function is called by the global window variable, unboundGetX() it's like writing window.unboundGetX() so the this will refer to the global scope which is "window" object so it's also like you wrote return window.x which is logically "undefined".

it will be better to bind your scope to the same object like this :

const module = {
  x: 42,
  getX: function() {
    return this.x;
  }
};

console.log(module.getX());

const unboundGetX = module.getX.bind(module); // we bind getX function to module scope instead of the global scope (which is the window variable)
console.log(unboundGetX());
sohaieb azaiez
  • 516
  • 3
  • 11
  • I really do not understand it, but will get back to your answer later, thanks. What puzzles me is the fact that the method module.getX is stored in a variable, so it should get normally accessed, whoever calls it. And what about the first Function call? Is it not called by the window object? Is this not also global? Why it will get access to the method? Thanks – Miloš Leng Mar 04 '21 at 20:29
  • you got module.getX as a reference and you put this reference in a variable called "unboundGetX" , but you did not call it yet .. Now, when you called it like this "unboundGetX()" , in the reality, the browser "window" variable is calling it in background like this "window.unboundGetX()" so that the "this.x" reference will refer to the "window" object not to the "module" object.. that's why i edited my answer by using "bind(..)" function, to bind your function reference to "module" instead of "window" object. – sohaieb azaiez Mar 04 '21 at 20:35
  • I mean the "x" property will refer to "window" not to "module", so that "this" will not be the "module" object, instead , it will be the "window" object .. that's why we should use "bind(..)" or "call(..)" or "apply(..)" functions , to handle scopes correctly. – sohaieb azaiez Mar 04 '21 at 20:37
  • 1
    Thanks, I am resolving the question now and will be studying your answer. – Miloš Leng Mar 04 '21 at 20:38
  • take it as a rule: every function (or let say method) wich is called like ".yourMethod()" will refer to the object whish called it before the "." , so if i say "myobject.itsMethod(...)" the "itsMethod" will refer to "myobject".. but what if i called a function without "." ? it's simple, it will refer automatically to the scope where it was called (in our case the global window object) so you can imagine it like it's called as "window.itsMethod(..)" so that the "this" will refer to the window object. Finally, that's why "x" is undefined because it is not defined in the "window" object. – sohaieb azaiez Mar 04 '21 at 20:41
  • thanks , you are welcome :) – sohaieb azaiez Mar 04 '21 at 20:41
  • That is a great explanation, thx once again! – Miloš Leng Mar 04 '21 at 20:55
  • you are welcome ^ ^ – sohaieb azaiez Mar 04 '21 at 20:55