关于闭包两道题目的思考

JS 闭包题目思考

最近在网上看到这样的两道题目

    代码片段一。
      var name = "The Window";
      var object = {
        name : "My Object",
        getNameFunc : function(){
          return function(){
            return this.name;
          };
        }
      };
      alert(object.getNameFunc()());

    代码片段二。
    var name = "The Window";
    var object = {
        name : "My Object",
        getNameFunc : function(){
          1  var that = this;
           2 return function(){  //zhi
               3 return this.name;
            4};
        }
    };
    alert(object.getNameFunc()());

据说是出自红宝书. 看的觉得很又意思, 又仔细的研究了一下.写一下心路历程.


第一个还好,大多数都会答错第二道题目. 我仔细在debug了一下这个运行过程. 运行顺序是这样的


运行顺序

1. 调用getName() 这个function. 返回了一个匿名的function.但是需要注意的是.这个匿名的function 并没有运行. 而是在object.getNameFunc()() 第一个function运行完成之后再返回. 然后运行第一个function. 所以运行过程应该是这样的
2. object.getNameFunc() //运行getName里面的语句.但是这个函数只有一个 return function.所以只运行了一个return function();

3. function(){...}=object.getNameFunc().//运行了getNameFunc后返回了这个function()正常情况下,这个function不会运行. 但是注意题目,object.getNameFunc()() 这里有两个括号.也就是在getNameFunc()运行之后. 又紧接着运行了 匿名的function(){...}所以第三步应该是这样.

4. function(){...}(); 运行匿名函数. return this.name.
#### 所以整个运行过程是这样 getNameFunc(){};>>>function(){};>>>alert(str). 需要注意的是.
  ** 在运行getNameFunc() 的时候只会返回那个匿名函数.而不会运行内部的匿名函数.**

  • 在搞清楚了运行过程的步骤,解决这两道题目就会特别简单.

第一道题

      代码片段一。
        var name = "The Window";
        var object = {
          name : "My Object",
          getNameFunc : function(){
            return function(){
              return this.name;
            };
          }
        };
        alert(object.getNameFunc()());

      1. 运行getNameFunc() 得到 匿名function(){} ps: 仅仅是得到这个匿名函数,并不运行.
      2. 运行function(){...} 得到了this.name. 因为这个函数是匿名函数,所以调用对象着是window.所以运行情况相当于是一个全局的函数.


        而   alert(object.getNameFunc()());  等价于下面的两步.


            1. function(){}=getNameFunc() //第一步
           2. alert(function(){return this.name}()); //第二步 运行这个匿名的函数


        所以当运行匿名函数的时候,调动对象是window. 所以return this.name 就返回了一个全局的name
        即 "The window"

第二道题

      代码片段二。
      var name = "The Window";
      var object = {
          name : "My Object",
          getNameFunc : function(){
            1  var that = this;
             2 return function(){  //zhi
                 3 return that.name;
              4};
          }
      };
      alert(object.getNameFunc()());
  1. 第一步运行 getNameFun();

    • 就是运行了两句话.
      1. var that =this //这个时候是obeject调用getNameFunc(),所以 that=object. 这个that 保存下来this 的直
      2. return function(); //只是return 没有运行.
  2. 第二步. 运行 getName()返回的匿名函数.即

     function(){  return that.name }();
    
    
    
     返回了that.name="My object".
     这个时候的this 其实是window对象.this.name="The window"
     但是这个时候返回的是that.name.所以返回 "My obejct"
    

总结

  • this 的直是不断在变化的. 所以如果想得到某个确定的直.就在他变化前保存下来.
  • 匿名对象的调用者是window 对象.
  • 闭包中返回的函数.当你不调用的时候是不运行的. 它仅仅是返回给你而已.
posted @ 2017-03-07 21:12  MaxProAim  阅读(192)  评论(0编辑  收藏  举报