《Javascript高级程序设计》这本书中关于this对象的一段话如何理解?

《Javascript高级程序设计》这本书里提到,每个函数在被调用时都会自动取得两个特殊变量时,只会搜索到其活动对象为止,因此永远不可能直接访问外部函数中的这两个变量。

所以是不是可以理解为会一直访问到全局变量才会停止呢(没有绑定的话)?以下是代码:

var name = "The Window";
var object = {
  name : "My Object",
  getNameFunc : function(){
    return function(){
      return this.name;
    };
  }
};
alert(object.getNameFunc()()); //"The Window"

非常感谢!

阅读 3.4k
5 个回答

1.this变量访问在运行时候才会被绑定
2.其他变量访问在定义(位置)时候被绑定

看这段代码应该可以理解一部分

var name = "The Window";
var object = {
  name : "My Object",
  getNameFunc : function(){
      return this.name;
  }
};
var fun = object.getNameFunc;
console.log(object.getNameFunc())//My Object
console.log(fun())// The Window

匿名函数具有全局性(匿名函数的this一般指向全局对象(window,global等)),需要注意的是this只与函数的执行环境有关,当函数作为某个对象的方法来“引用”时,this指向这个对象,比如说:

var obj = {
    name : "obj",
    say : function(){
        console.log(this);
    }
};

var obj2 = {
    name : "obj2"
};
obj2.say = obj.say;
obj2.say();  //输出obj2
//这里say明明是在obj里面定义的方法,obj2只是对其进行引用,但this最终指向obj2,所以this指向仅仅与函数的执行环境有关。

当然还有一些比较特殊的,像es6的箭头函数,却是与函数的定义环境有关,比如说:

var obj = {
    name : "obj",
    say : function(){
        return () => {console.log(this)};
    }
};

var obj2 = {
    name : "obj2"
};

obj2.say = obj.say();
obj2.say(); //输出obj
//这里箭头函数为什么要包含在一个function里面进行返回是因为需要调整this的指向,上面说过箭头函数this指向与定义环境有关,在say方法的内部的this才是指向obj的,如果直接进行箭头函数赋值,this则会指向定义环境window

上面是本人的理解,如果有错误欢迎指正

在最新的ECMAScript262语言规范的8.1.1中提到一个词叫Environment Recorders,建议有兴趣可以看下,在上一版的规范中貌似叫个execution context,就是执行上下文。

可以这样理解,在解释器的实现中Environment Recorders就是用来记录一个环境栈信息,栈么,就是后进先出,通俗点说就是吃多了吐出来,而堆是先进先出,就是吃多了拉出来。栈底记录是的全局环境,如window 或 global环境。在函数执行时记录器会把此函数的执行环境压入环境栈,此时活动的就是这个环境,那么this指向就引用这个环境对象。当执行完成时,把这个环境从栈顶弹出去。基本就是这么一个过程,当然栈里最少都会保持一个环境。

那什么时候会往环境栈里压栈值就应该能猜的出来,以对象方法的调用或人为干预时,如通过.call,.apply,.bind时等。object.getNameFunc()的过程就是,object进栈--执行----->object出栈,等到它返回的匿名函数运行时环境栈就只剩全局了,this引用自然访问到的是'The window'。

至于它说的只会访问到活动对象为止,可以这样验证

var object = {
  getNameFunc : function(){
    console.log(this.name);
    return function(){
      return this.name;
    };
  }
};

console 这一行应该打出一个undefined,而不是打出The window,也就是说当前活动对象上没有,不会再搜索栈底的其它环境,这和作用域是不一样的。

return function(){}
这个函数是全局的

函数里的this只有被运行时才会被绑定,而这个函数执行的时候是普通方式,所以里面的this永远被标记为全局对象,反正一个函数或者方法被执行的时候最多就四种,有本书叫你不知道的JS这里面将this我觉得讲的还挺不错的,你可以直接翻到那边看看。
其实js的this有一定迷惑性,但其实都逃脱不了那四种情况,安情况对应就好,不然很容易被绕晕

推荐问题
宣传栏