function foo() { console.log( this.a );}var obj = { a: 2, foo: foo};obj.foo(); // 2
this指向了obj,因为foo执行时的call-site(可以理解为调用时所在作用域)在obj上面。注意是运行的时候,和在哪里声明的没有关系。
call-site and call-stack
call-site姑且理解为调用域,call-stack为调用栈。如下代码可以辅助我们理解
function baz() { // call-stack is: `baz` // so, our call-site is in the global scope console.log( baz ); bar(); // `bar` // so, our call-site is in `baz` console.log( bar ); foo(); // `bar` -> `foo` // so, our call-site is in `bar` console.log( foo );}baz(); // <-- call-site for `baz`
理解之后再回头看开头的例子,是不是感觉清晰了很多。其实this只是指向了它的call-site
还有如下玩法:
function foo() { console.log( this.a );}var obj2 = { a: 42, foo: foo};var obj1 = { a: 2, obj2: obj2};obj1.obj2.foo(); // 42implicitly 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 objectbar(); // oops, global
虽然bar引用了obj上的foo,但实际上相当于是直接对foo引用而已,所以会默认绑定到全局。
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 objectdofoo( obj.foo ); // oops, global
