面试官问,什么是闭包,我该怎么答?
我想答出一段话,或者定义,而不是一个函数实例
能访问外部函数的变量的函数,举个例子:
function a(x){
var z=3;
function b(y){ // 这个就是闭包,它能访问外部函数a的x和z变量
console.log(x+y+(++z));
}
return b;
}
定义 函数a、函数b
满足:
就形成闭包了。
怎么答看各人表达,意思到就行了。。。
// 例子自行体会
function b(){
var z = 3;
function a(y){
console.log(z + y); // a 引用了 b作用域内的 变量z
}
return a;
}
var c = b();
c(1); // a 可以在 函数b 外执行
看了所有的答案,大家的理解都差不多,只在一点上有分歧: 闭包是否必须被外界访问到?
答案是: 否!
function a(x){
var z=3;
function b(y){ // 这个就是闭包,它能访问外部函数a的x和z变量
console.log(x+y+(++z));
}
return b;
}
去掉return 是否还是闭包?
答案是: 是!!!!!!!!!!
它既是内部函数,也是闭包,这两者并不冲突。
mdn上闭包的定义:
闭包是函数和声明该函数的词法环境的组合。
只要满足,这是一个函数,这个函数内部使用了外部变量,它就是一个闭包。
mdn上的第一个例子:
function init() {
var name = "Mozilla"; // name 是一个被 init 创建的局部变量
function displayName() { // displayName() 是内部函数,一个闭包
alert(name); // 使用了父函数中声明的变量
}
displayName();
}
init();
因为diaplayName无法再次访问到,因此闭包中的name也会被回收掉。
从定义上讲,displayName是个闭包,虽然没有啥卵用。
---------------分割线--------------------------
另外,根据定义,任何函数都可以是广义上的闭包,因为词法环境中的外部引用有可能是空。
所以如果面试官问你闭包,那我建议你应该先问他,是回答闭包的定义还是多数实践,是回答狭义还是回答广义。
8 回答4.6k 阅读✓ 已解决
6 回答3.4k 阅读✓ 已解决
5 回答2.8k 阅读✓ 已解决
5 回答6.3k 阅读✓ 已解决
4 回答2.2k 阅读✓ 已解决
4 回答2.8k 阅读✓ 已解决
3 回答2.4k 阅读✓ 已解决
推荐高程,网上的理解都是个人的,可以参考,但有自己的理解才是最好的。
我认为比较好的回答是:
1、闭包条件:a、外层函数嵌套内层函数;b、内层函数引用外层函数中的变量;c、外层函数返回内层函数;
2、js垃圾回收机制:当一个变量不被引用的时候会被回收
3、每个函数声明的时候,会生成一个包含该函数作用域内部变量的活动对象
举一个简单例子分析:
上述例子在不存在闭包的情况应该是,我执行完a以后,销毁了函数作用域,那么x也被销毁了,那么两次执行的结果应该是两次1。但第二次是2,说明内部的x并没有被销毁,也就是a函数作用域被中的x被保存下来了。
结合上述3点开始分析:
a函数声明时,创建了一个包含a函数作用域内部变量的活动对象,可以叫他aa,aa内部有局部参数x;
b函数声明时,引用了aa中的x;
a函数执行后,全局变量result引用了b函数;
那结合JS的垃圾回收机制,x被引用不会被销毁,b被引用不会被销毁,result是全局变量也不会被销毁,x得以保留,这样就形成了闭包.而由于aa中的y没有被引用,所以被销毁了。
上面是我的理解,最后可以回答一下闭包的应用,这里就不做回答了,网上很多
综上所述,建议的回答就是上述3点加上应用