0

So the this of function depends on its execution context (place where its being called)

function foo(){
console.log(this) // will print window

}

foo()

And this one

const obj={
  fun:function(){

  console.log(this)
}
 
}
obj.fun(); //will print the obj

I am just confused how the execution context obj gets loaded to call stack from heap

enter image description here

Or am I missing something here ? .Please help me out

gANDALF
  • 360
  • 4
  • 21
  • 1
    The value of `this` is not related to the execution context. It depends on *how* a function is called. [How does the "this" keyword work?](https://stackoverflow.com/q/3127429) – VLAZ Jan 01 '22 at 10:47
  • @VLAZ I am referring men -https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this – gANDALF Jan 01 '22 at 10:48
  • Yes, and my comment stands - the execution context is not related at all to the value of `this`. – VLAZ Jan 01 '22 at 10:49
  • I know that question ,I am just wondering how things are working internally – gANDALF Jan 01 '22 at 10:49
  • 2
    It's simple, the value is always the caller unless you use bind(), call(), and apply(). If no caller is specified it's `window`. In case of func.bind(obj), the obj is wrapped by the bound function and upon call internally it calls function on the bound object. I found [this explanation](https://stackoverflow.com/a/14307667/15273968) very useful. Modern classes are just syntactical sugar internally they expand to old style code in [babel](https://babeljs.io/). – the Hutt Jan 03 '22 at 15:54

2 Answers2

2

Enclosing Scopes

Forgetting about this for a moment. The concept of "execution context" is called Closure in Javascript. The MDN article explains it well.

To get a better sense of it, let's use a variable called a instead of this :

const a = 1;

function foo() {
  //can access `a` here
  function bar() {
    //can also access `a` here
  }
}

These functions have access to the outer scopes where they were declared. This is the "execution context", as you called it, though this is the wrong terminology for Javascript. "Scope" or "lexical scope" would be the correct terms.

No matter where you call those functions, they will still be able to print a.

Call Stack and Heap

The MDN article on Closures has this to say:

Closure Scope Chain
Every closure has three scopes:

  • Local Scope (Own scope)
  • Outer Functions Scope
  • Global Scope

The thing to note about these is that they are established at parse time, NOT execution time.

While Javascript does have a call stack and a heap, these have nothing to do with scope or closures. Scopes are a property of the function, and remain the same from the time the Javascript is first parsed until the code has finished running.

About this

this is a variable that depends entirely on how the function was initialized and called. The MDN article may again prove useful here.

Let's look again at your example function, with some inline comments and examples:

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

// Sure, calling `foo()` right now will print `window` if you're in a browser
foo(); //prints `window` in a browser

// But any use of `new` keyword will change `this` (including classes)
const obj = new Object(); 
obj.foo = foo;
obj.foo(); //prints `{ foo: [Function: foo] }`

// Similarly, assigning `foo` to a plain object will also change `this`
const obj = {}; 
obj.foo = foo;
obj.foo(); //prints `{ foo: [Function: foo] }`

// Lastly, any of the `Function.prototype` methods `bind`, `apply`, `call` 
// intentionally change `this`
//
// `bind()` returns a new function:
const boundFunction = foo.bind({"this is a property": "and a value, see!?"});
boundFunction(); //prints `{ 'this is a property': 'and a value, see!?' }`
//
//`apply()` and `call()` both execute the function 
// (the difference between the two is in how arguments are passed,
// see the MDN articles on 
// [apply](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply#syntax) and on
// [call](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call#syntax) for more details)
foo.apply({bar:1}); //prints `{ bar: 1 }`
foo.call({baz: 2}); //prints `{ baz: 2 }`
Codebling
  • 10,764
  • 2
  • 38
  • 66
2

This in Javascript behaves differently in browser & Node env. this in global context points to window in browser and globalthis in Node. In this case 'This' is pointing on calling object, i.e obj. when a fn is being called js looks this in its lexical environment. You can also bind this context with apply,bind,call.

const obj = {name:'Irfan',fn:function(){console.log(this.name)}} // will print Irfan

Here this is pointing pointing to obj i.e this=obj(this.name=obj.name), but in arrow fn this is not bound by default.