在全局环境下有以下代码

var oTemp={a:1};

function foo() {

  console.log(this);

  (function() {

    console.log(this);

  })();

}

执行foo()时,打印结果为
window(object)

window(object)

执行foo2.call(oTemp)时,打印结果为
oTemp(object)

window(object)

原因是,call的功能是在一个特定的作用域中调用函数,所以foo.call(oTemp)相当于是做了以下工作
oTemp.foo=foo;
oTemp.foo();

此时foo作为oTemp的一个属性,this指向oTemp,也即改变了foo的作用域。

但是执行到匿名函数的时候,匿名函数的闭包中,this依然指向window,这说明匿名函数的闭包是在foo的作用域改变之前形成的,而闭包一旦形成就不会改变,所以匿名函数中打印的依然是window.

也可以从foo.call(oTemp)的执行过程来理解,执行foo.call(oTemp)时,首先要有一个foo函数的实例,之后才调用这个实例的call方法。而当foo实例形成的时候,它的作用域链就确定下来了,其内匿名函数的作用域链也确定下来了,之后调用该实例的call方法,改变了foo实例的作用域链,但是改变不了匿名函数的作用域链。

posted on 2017-10-27 10:23  RickHammer  阅读(159)  评论(0)    收藏  举报