微信小程序微信小程序JavaScript

两段代码彻底看透闭包、函数作用域及this上下文

2018-12-10  本文已影响1人  独孤久见

相信大多做前端的同学对这几个概念都不会太陌生,但是真正能够看透看懂应该不多,今天看了 阮一峰老师的文章感觉讲的很好,特别是后面写的例子更是一针见血,正如他所说的,理解了那两道题就彻底了解闭包.但是他后面没有对这两个例子过多分析,可能让我们自己去真正的领悟真正的看清.
原文地址:学习Javascript闭包

例子1

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

例子2

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

栗子分析

在这两段代码中,都有一个变量name做为全局变量.,然后再声明一个对象,里面有一个name属性,还有一个函数getNameFunc.getNameFunc里面直接返回一个函数.还有一点差别是例2里面的this赋值给了that变量.

为什么例1最后的结果是"The Window"而不是object里面的name"My object"呢?

首先,要理解函数作为函数调用和函数作为方法调用。

我们把最后的一句拆成两个步骤执行:

var first = object.getNameFunc();
var second = first();

其中第一步,获得的first为返回的匿名函数,此时的getNameFunc()作为object的方法调用,如果在getNameFunc()中使用this,此时的this指向的是object对象。

第二部,调用first函数,可以很清楚的发现,此时调用first函数,first函数没有在对象中调用,因此是作为函数调用的,是在全局作用域下,因此first函数中的this指向的是window。

在闭包中:
内部函数可以访问定义它们的外部函数的参数和变量(除了this和arguments之外)
如果需要访问对象的name属性的话,就需要显示的定义一个变量that来引用this,而这个变量此时就指向object对象了。所以第一个例子闭包函数无法访问这个this,它只能访问到全局的this。例2中this就是objec对象把this赋值that就是一个局部变量,所以可以返回My Object.


有不同看法欢迎交流.

上一篇下一篇

猜你喜欢

热点阅读