乐趣区

3个闭包面试题解析

理解闭包形成的原因,理解定义时和运行时的区别。

面试题 1

var num = 1;
var o = {
    num: 2,
    add: function() {
        this.num = 3;
        console.log('add', this);
        (function() {console.log('closure', this);
            console.log(this.num);
            this.num = 4;
        })();
        console.log(this.num);
    },
    sub: function() {console.log(this.num);
    }
}
o.add();
console.log(o.num);
console.log(num);
var sub = o.sub;
sub();

// 请写出输出结果 

zyx456 的解释:

01,o.add();

第一个 console.log(‘add’, this);// 输出 o 这个对象。

在对象方法中,方法中的 this 指向这个对象。

第一个 this.num = 3;

表示:o.num =3;

02,匿名自执行函数中的 this,指向全局环境变量。为 window。

所以

(function() {​            console.log('closure', this);// 这里的 this 是指向哪里?window

​            console.log(this.num);//1

​            this.num = 4;//window.num = 4;

})();

匿名自执行函数的 this.num 为 window.num。为 1。

this.num = 4;//window.num = 4;

03,

console.log(o.num);//3,因为前面修改了 o.num=3;

04,console.log(num);//4

这里,num 为 window.num。

05,var sub = o.sub;

sub();//4

zyx456:sub 为函数。全局函数中的 this 指向全局环境,也就是 window。

所以为 window.num 为 4;


面试题 2

function fun(n,o) {console.log(o)
  return {fun:function(m){return fun(m,n);
    }
  };
}
var a = fun(0);  
a.fun(1);  a.fun(2);  a.fun(3);//undefined,?,?,?
var b = fun(0).fun(1).fun(2).fun(3);//undefined,?,?,?
var c = fun(0).fun(1);  c.fun(2);  c.fun(3);//undefined,?,?,?
// 问: 三行 a,b,c 的输出分别是什么?

zyx456 分析:

var a =fun(0);

首先输出 console.log(o);// o 未定义,为 undefined;


a =  {fun:function(m){return fun(m,0);
    }
}
a.fun(1);// 返回 fun(1,0);=> console.log(0)=>0

a.fun(2);// 返回 fun(2,0);=>console.log(0)=>0

a.fun(3)// 返回 fun(3,0);=>console.log(0)=>0


所以:第一行输出 undefined,0,0,0

然后看第二行:var b = fun(0).fun(1).fun(2).fun(3);

fun(0)

首先输出 console.log(o);// o 未定义,为 undefined;

等效于

 {fun:function(m){return fun(m,0);

   }
}

fun(0).fun(1)

return fun(1,0)

fun(1,0) 先输出 =>console.log(0)=>0

最后 return 结果为


 {fun:function(m){return fun(m,1);
    }
}


fun(0).fun(1).fun(2)

等同于

return fun(2,1)

fun(2,1)-> 输出 console.log(1);=>1

最后 return 结果为

{fun:function(m){return fun(m,2);
       }
}

fun(0).fun(1).fun(2).fun(3)

等同于

return fun(3,2)

fun(2,1)-> 输出 console.log(2);=>2

最后 return 结果为


{fun:function(m){​        return fun(m,2);
​    }
}


所以:第一行输出 undefined,0,1,2

最后看第三行:var c = fun(0).fun(1); c.fun(2); c.fun(3);

var c=fun(0).fun(1);

同第二行的 b。会输出 undefined 和 0,

c 为

 {fun:function(m){return fun(m,1);
    }
}

c.fun(2)

return fun(2,1)=> 输出 1。可以看第二行 b。

c.fun(3)

return fun(3,1)=> 输出 1。可以看第二行 b。

所以:第一行输出 undefined,0,1,1

面试题 3

// 最基础题
for(var i = 1; i < 10; i ++){setTimeout(function(){console.log(i);
    }, 1000);
}

// 变体一
for (var i = 1; i < 10; i++) {(function(i){setTimeout(function(){console.log(i);
        }, i * 1000);
    })(i);
}

// 变体二
for (var i = 1; i < 10; i++) {(function(){setTimeout(function(){console.log(i);
        }, i * 1000);
    })();}

// 变体三
for (var i = 1; i < 10; i++) {(function(){setTimeout(function(i){console.log(i);
        }, i * 1000);
    })();}

zyx456:

最基础:

1s 后运行定时器,此时 for 循环已结束,i 为 10。

变体 1:

依次 1 秒输出一个数字,闭包会使用 for 循环的值。

依次输出 1~9

变体 2:

依次每隔 1 秒输出 10,10,10.。。。。

变体 3:

在匿名自执行函数中,i 未定义。所以输出 9 个 undefined。

退出移动版