JavaScript闭包面试题详解

说说它们的输出情况

第一题

var name = "The Window";
var object = {
    name: "My Object",
    getNameFunc: function () {
        return function () {
            return this.name;
        };
    }
};
console.log(object.getNameFunc()());  // The window
// var f =   object.getNameFunc();
// f();
详解:
object.getNameFunc()是一个表达式,返回的值是一个函数。
function () {return this.name;};
我们把object.getNameFunc()赋值给一个变量f来解释
var f =   object.getNameFunc();
那输出内容object.getNameFunc()() 等同于 
f();等同于
function () {return this.name;}()
所以最后是哪个对象调用了最后执行的函数呢?
很明显没有,那就是默认的系统对象window。
this指向window
那this.name就指向全局变量 "The Window"

第一题运行结果:

JavaScript闭包面试题详解

第二题


    var name2 = "The Window";
    var object2 = {
        name2: "My Object",
        getNameFunc: function () {
            var that = this;
            return function () {
                return that.name2;
            };
        }
    };
    console.log(object2.getNameFunc()());   // My Object
    
详解:
同理第一题
object2.getNameFunc()是一个表达式,返回的值是一个函数。
function () {return that.name2};
输出内容,object2.getNameFunc()()等同于
function () {return that.name2}();
然后返回that.name2
 that是一个局部变量,先从本函数作用域找,找不到再往上一层作用域找。
 在上一层函数getNameFunc的作用域找到了。
 var that = this;
 getNameFunc是object2这个实列对象的属性。
 
 this 的指向分为以下两种情况:
1)在构造函数使用 thisthis 指向实例化之后的对象。
2)在方法(所谓函数本质上其实是 window 对象的方法)中使用thisthis 指向调用该方法的对象。
所以this指向object2
所以,that.name2 输出内容是局部变量name2  "My Object"

JavaScript闭包面试题详解

第三题

<script>
    function fun(n, o) {
        console.log(o);
        return {
            fun: function (m) {
                return fun(m, n)
            } 
        }
    }
    var a = fun(0);    // 输出 undefined 
    a.fun(1);          // 0
    a.fun(2);          // 0   
    a.fun(3);          // 0    
    console.log('');

    var b = fun(0).fun(1).fun(2).fun(3);
    // undefined   0  1  2
    console.log('');

    var c = fun(0).fun(1);   // 输出 undefined 0
    c.fun(2);   // 1
    c.fun(3);   // 1
</script>
详解一:
    var a = fun(0);    // 输出 undefined 
    a.fun(1);          // 0
    a.fun(2);          // 0   
    a.fun(3);          // 0    
    console.log('');
首先分析题目结构
 function fun(n, o) {...}
 是一个带有两个形参的函数。
 进入函数后就会输出第二个形参的值
  console.log(o);
  再返回return 一个对象: {fun: function (m){...}}
  对象里面再返回一个调用函数return fun(m, n)
  这个调用函数调用的就是 function fun(n, o) {...}
详解一:
 fun(0)带入函数 fun(n, o)
 n=0,o没有被赋值为undefined
 所以 var a = fun(0);    // 输出 undefined 
  a.fun(1)等同于fun(0).fun(1),fun(0)返回的是一个对象,
  返回值是对象还可以接着调用fun(1),且对象里面还有一个调用函数,
fun(1)带入fun(0)的返回值fun: function (m) {return fun(m, n)}所以调用函数fun(m, n),变量m=1,变量n 在当前作用域中没有,那就往上找第一次 fun(0)的时候 n =0,由于调用还没有结束,变量值没有被销毁,所以 n = 0;
 所以 fun(m, n) 就是fun(1, 0),因为这个调用函数调用的是 function fun(n, o) {...} 实参1给你n,实参0给o
输出内容 a.fun(1)的值是0  
同理  a.fun(2);          // 0   
     a.fun(3);          // 0   
详解二:
 var b = fun(0).fun(1).fun(2).fun(3);
  // undefined   0  1  2
  解题思路同详解一,因为函数fun()的返回值是一个对象,对象可以调用方法。
  抽丝剥茧一层一层往下捋。变量b输出内容的变化就是o的值都是上一次调用的n的值。
  
  详解三:
      var c = fun(0).fun(1);   // 输出 undefined 0
    c.fun(2);   // 1
    c.fun(3);   // 1
    同理一和二。

JavaScript闭包面试题详解
肝了两小时,有帮助到的小伙伴记得点个赞给小主一个鼓励哦!谢谢!
如有错误欢迎评论留言哦(每一条都会看)!

匿名

发表评论

匿名网友