2

From what I have read and understood, execution context(this) of a function has nothing to do with where its declared, but from where it was invoked (call site). Consider 2 cases, where foo is defined in global context-

//1.
function foo(){ console.log(this); }

var obj = {
    x: foo,
};

obj.x(); //prints obj because foo was called "on" obj object

//2.
function foo(){ return this; }

var obj = {
    x: function(){ console.log(foo()); },
};

obj.x(); //prints window object.

I have confusion in 2nd case. Though I understand context for x function is obj, I can't comprehend how come foo was called on window object from within x function (whose context is in fact obj)? Am sure there are numerous questions on this topic, I was unable to find something similar to this kind of example. Thanks.

Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151
mustafa1993
  • 541
  • 1
  • 5
  • 17
  • 3
    The invocation `foo()` has no calling context, thus inside of `foo`, `this` will refer to `window`. – CertainPerformance Oct 13 '18 at 08:28
  • 2
    I think any proper documentation will clear `this` up (pun intended). https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this#Function_context – Sergiu Paraschiv Oct 13 '18 at 08:33
  • 1
    Oh that's it. So can I deduce if there is no calling context, like someObject.foo(), this will _always_ refer to window no matter from where it was called? – mustafa1993 Oct 13 '18 at 08:34
  • 1
    Unless you use strict mode, which you should. – Sergiu Paraschiv Oct 13 '18 at 09:00
  • 1
    No, it doesn't have anything to do with *from where* a function is called. It only matters *how* it is called - and `obj.x()` is a method call while `foo()` is not. – Bergi Oct 13 '18 at 09:19

2 Answers2

0

I will try to give a short answer:

The context of a function is usually the object it is assigned on. Since in the second case foo is not declared to be an object's property, it's context is the global (window) object.

If you want to pass the object as the context to foo you have to call it with foo.call(this, ...parameters) or with foo.apply(this, parameters) or you can create a variable with the function bound to the object:

const myFoo = foo.bind(this);
myFoo(...parameters);

Here is an article with an extended explanation.

mightyplow
  • 519
  • 2
  • 6
  • 11
0

As other answers and comments explain: your execution context is NOT bound to obj when foo is called as such. As you are expecting this to happen you might instead want to say:

foo.call(obj) 

Basically you are binding this within foo to the object obj which is the first argument.

More at MDN

trk
  • 2,106
  • 14
  • 20