Briefly discuss the implicit binding of this in javascript

  • 2020-12-26 05:33:01
  • OfStack

So let's look at an example


function foo() {
  console.log( this.a );
}
var obj = {
  a: 2,
  foo: foo
};
obj.foo(); // 2

this points to obj because the call-ES8en (which is understood to be the scope of the call) when foo executes is above obj. Notice when it's running, it doesn't matter where it's declared.

call-site and call-stack

call-site is understood as the calling domain, and ES18en-ES19en is the call stack. The following code will help us understand


function baz() {
  // call-stack is: `baz`
  // so, our call-site is in the global scope

  console.log( "baz" );
  bar(); // <-- call-site for `bar`
}

Call bar() in baz(), so the call domain of bar is baz, and the call stack of bar has only baz. baz itself is exposed to the global scope, so its calling domain is also in the global scope.


function bar() {
  // call-stack is: `baz` -> `bar`
  // so, our call-site is in `baz`
  console.log( "bar" );
  foo(); // <-- call-site for `foo`
}
function foo() {
  // call-stack is: `baz` -> `bar` -> `foo`
  // so, our call-site is in `bar`
  console.log( "foo" );
}
baz(); // <-- call-site for `baz`

After understanding and then look back at the beginning of the example, is it a lot clearer. this is just pointing to its call-ES35en

Here's how:


function foo() {
  console.log( this.a );
}
var obj2 = {
  a: 42,
  foo: foo
};
var obj1 = {
  a: 2,
  obj2: obj2
};
obj1.obj2.foo(); // 42
Implicitly Lost (Implicit loss) 
function foo() {
  console.log( this.a );
}
var obj = {
  a: 2,
  foo: foo
};
var bar = obj.foo; // function reference/alias!
var a = "oops, global"; // `a` also property on global object
bar(); // "oops, global"

Although bar refers to foo on obj, it is essentially a direct reference to foo, so it is bound to the global by default.


function foo() {
  console.log( this.a );
}
function doFoo(fn) {
  // `fn` is just another reference to `foo`
  fn(); // <-- call-site!
}
var obj = {
  a: 2,
  foo: foo
};
var a = "oops, global"; // `a` also property on global object
doFoo( obj.foo ); // "oops, global"


Related articles: