Let’s look at an example first
function foo() { console.log( this.a ); } var obj = { a: 2, foo: foo }; obj.foo(); // 2
This points to obj, because the call-site when foo is executed (can be understood as the scope when calling) is above obj. Note that it is at runtime and has nothing to do with where it is declared.
call-site and call-stack
Call-site is temporarily understood as the call domain, and call-stack is the call stack. The following code can 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 calling domain of bar is baz. At this time, the call stack of bar is only baz; and baz itself is exposed in the global scope, so its calling domain also affects the global scope. in the domain.
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 it, look back at the example at the beginning and it will become much clearer. In fact, this just points to its call-site
There are also ways to play as follows:
function foo() { console.log( this.a ); } var obj2 = { a: 42, foo: foo }; var obj1 = { a: 2, obj2: obj2 }; obj1.obj2.foo(); // 42 Implicitly Lost(隐式丢失) 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 actually equivalent to directly referencing foo, so it will be 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"