gANDALF
gANDALF

Reputation: 238

How execution context other than window object is moved in stack In Js

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

Upvotes: 0

Views: 420

Answers (2)

Irfan Razzaq
Irfan Razzaq

Reputation: 51

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.

Upvotes: 2

Codebling
Codebling

Reputation: 11382

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 }`

Upvotes: 2

Related Questions