首页 > js闭包代码的疑问?

js闭包代码的疑问?

这段代码为什么会调用全局的name;this指向怎么不是这个object对象呢?

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

这代码就指向了这个对象,不理解其中的奥秘?

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

首先,请记住在function () {}内的this是延迟绑定的,而ES2015的箭头函数中的this,是已经被绑定好的,this取决于定义时this的指向,相当于function (){}.bind(this)
this的指向只有两种情况:

  1. object.fun(),就像题主说的第二种情况:


  var object = {
    name : "My Object",
    getNameFunc : function(){
      var that = this;
      return function(){
        return that.name;
      };
    }
  };

这种情况下this指向的是其.之前的那个对象,这一点同样适用于全局中的函数,因为我们在全局中定义函数,相当于给我们的全局变量添加方法,在浏览器中看也就是给我们的window添加方法,所以这种方法内的this,指向.之前的对象也就是window
第一种情况:


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

调用obj.getNameFunc()返回了一个函数,被添加为了全局方法,所以指向的是window

  1. this指向null时,在非严格模式下会被转为指向全局:

在看题主的这一段代码时,我们首先一个概念,那就是活动对象,也就是AO,这个对象是虚拟出来的,在外界访问不到,也就是我说的null的情况,AO在我们调用函数时生成,我们在函数内定义的变量可以理解为这个对象的属性,argumenst也可以理解为AO对象的属性,但是这个AO对象在外界访问时为null,所以题主在getNameFunc内定义函数相当于给getNameFunc函数的AO添加方法,由于AO对象在外界看来为null,所以在调用函数时this指向null,非严格模式下指向全局。


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

这种情况下,this指向的也是全局,用我说的情况2就可以解释。
个人理解,欢迎拍砖与讨论。


对于javascript中this的问题太多了,,,看多了容易混乱,就记住几个重点就好了: 1.this的指向是在运行时决定的,函数中的this,谁调用的他,他就指向谁。 2.bind,call,apply可以改变this的指向。3.ES6的箭头函数中的this是定义时就绑定了的。另外一点和this无关和你这个例子有些关系的就是:函数会创建新的作用域。


this这个关键字指代的内容是一直都在变动的,随着this所在的代码块的不同,this指代的也不尽相同。
第一段代码里,getNameFunc里面又嵌套了一个匿名的function,这意味着其实每次执行的匿名的function都是一个“新生成“的function,这个”新生成“的function所在的执行上下文就是window(这与你代码如何嵌套无关),所以匿名function内的this指代的就是window
另外一点,在浏览器环境下,你的脚本声明的所有全局变量,实际上都是window对象的属性,所以var name="The window"实际上就等同于window.name="The window"
第二段代码,var that=this的作用,是把getNameFunc的执行上下文传递给”新生成“的匿名functionthat指代了object,因此匿名function的作用跟你再在外面写个funcion(){return object.name}是一样的。


看了楼上几位前辈的答案,我也来做个简单粗暴的回答吧..

1、函数体中的this指向调用该函数的对象(除了call,apply等特殊情况)。

2、函数体中的return放在函数调用的地方。

所以你代码中的第一种情况:

alert(object.getNameFunc()());

等同于

alert((function(){return this.name;})());

所以该函数执行的时候,函数体中的this在非严格模式下会被转为指向全局(引用@zp1996),弹出window.name

第二种情况:

在执行 var that = this; 这条语句的时候,this指向的是调用 getNameFunc 方法的对象,即object。

所以 that 也指向object

代码中并没有其他地方改变了that的指向,所以在执行 return that.name; 时,that依旧指向object,与this无关。

【热门文章】
【热门文章】