本文目录
Javascript闭包函数
提问
该问题可能描述不清,建议你重新提问
Javascript的闭包是什么意思 有什么用
我有更好回答

PHP交流者之家
电脑网络认证团队 推荐于 2017-09-06
一、什么是闭包?
“官方”的解释是:所谓“闭包”,指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。
相信很少有人能直接看懂这句话,因为他描述的太学术。我想用如何在Javascript中创建一个闭包来告诉你什么是闭包,因为跳过闭包的创建过程直接理解闭包的定义是非常困难的。看下面这段代码:
function a(){
var i=0;
function b(){
alert(++i);
}
return b;
}
var c = a();
c();
这段代码有两个特点:
1、函数b嵌套在函数a内部;
2、函数a返回函数b。
这样在执行完var c=a()后,变量c实际上是指向了函数b,再执行c()后就会弹出一个窗口显示i的值(第一次为1)。这段代码其实就创建了一个闭包,为什么?因为函数a外的变量c引用了函数a内的函数b,就是说:
当函数a的内部函数b被函数a外的一个变量引用的时候,就创建了一个闭包。
我猜想你一定还是不理解闭包,因为你不知道闭包有什么作用,下面让我们继续探索。
js闭包面试题
//首先你的代码等价于下面的代码
function getFuns() {
var funs = [];
var i = 0;
funs[i] = function() {
console.log(i);
};
i = 1;
funs[i] = function() {
console.log(i);
};
i = 2;
funs[i] = function() {
console.log(i);
};
i = 3;
return funs;
}
var arr = getFuns();
arr[0]();
arr[1]();
arr[2]();
//无论哪调用function(){console.log(i);};这个函数,那个i都只有那一份,
//虽然i的作用域在getFuns里面,但当你在外面用这种方式间接使用到i时,
//它的生命周期被延长。
//这样输出2 2 2
function getFuns() {
var funs = [];
for (var i = 0; i < 3; i++) {
var a = i;
funs[i] = function() {
console.log((a))
};
}
return funs;
}
var arr = getFuns();
arr[0]();
arr[1]();
arr[2]();
//这样就可以输出0 1 2
function getFuns() {
var funs = [];
for (var i = 0; i < 3; i++) {
let a = i;//或者const a = i;
funs[i] = function() {
console.log((a))
};
}
return funs;
}
var arr = getFuns();
arr[0]();
arr[1]();
arr[2]();
//这样也可以输出0 1 2
function getFuns() {
var funs = [];
for (var i = 0; i < 3; i++) {
funs[i] = (function(x) {
return function() {
console.log(x)
};
})(i);
}
return funs;
}
var arr = getFuns();
arr[0]();
arr[1]();
arr[2]();
//
js闭包面试题经典
主要问题在于,自执行函数没有形参i,如果加一个形参i,输出的就是0-4了。如这样
for(var i =0;i<5;i++){
(function(i){
setTimeout(function(){
console.log(i)
},i*1000)
})(i)
}
这就是作用域的问题,for循环每执行一遍,都会生成一个异步函数setTimeout,由于这个时候是同步的,自执行函数里边的i,读取的就是每次for循环的i,所以每次执行相差1秒。然后js是单线程的,setTimeout需要等for执行完之后执行。这时候,for循环执行完使得i的值变为5,而自执行函数没有形参,setTimeout回调函数读的变量是自执行函数外的变量i,所以输出为5。也就是每隔一秒输出一个5。
你可以试着把5变成更大的数,也是一样的,输出的就是这个数。
彻底理解js中的闭包
要理解闭包,首先必须理解Javascript特殊的变量作用域。
变量的作用域无非就是两种:全局变量和局部变量。
Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量。
Js代码
var n=999;
function f1(){
alert(n);
}
f1(); // 999
另一方面,在函数外部自然无法读取函数内的局部变量。
Js代码
function f1(){
var n=999;
}
alert(n); // error
这里有一个地方需要注意,函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量!
Js代码
function f1(){
n=999;
}
f1();
alert(n); // 999
--------------------------------------------------------------------------------------------------------
二、如何从外部读取局部变量?
出于种种原因,我们有时候需要得到函数内的局部变量。但是,前面已经说过了,正常情况下,这是办不到的,只有通过变通方法才能实现。
那就是在函数的内部,再定义一个函数。
Js代码
function f1(){
n=999;
function f2(){
alert(n); // 999
}
}
在上面的代码中,函数f2就被包括在函数f1内部,这时f1内部的所有局部变量,对f2都是可见的。但是反过来就不行,f2内部的局部变量,对f1 就是不可见的。这就是Javascript语言特有的“链式作用域”结构(chain scope),
子对象会一级一级地向上寻找所有父对象的变量。所以,父对象的所有变量,对子对象都是可见的,反之则不成立。
既然f2可以读取f1中的局部变量,那么只要把f2作为返回值,我们不就可以在f1外部读取它的内部变量了吗!
Js代码
function f1(){
n=999;
function f2(){
alert(n);
}
return f2;
}
var result=f1();
result(); // 999
--------------------------------------------------------------------------------------------------------
三、闭包的概念
上一节代码中的f2函数,就是闭包。
各种专业文献上的“闭包”(closure)定义非常抽象,很难看懂。我的理解是,闭包就是能够读取其他函数内部变量的函数。
由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成“定义在一个函数内部的函数”。
所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。
以上就是关于js面试闭包完美回答 ,Javascript闭包函数的全部内容,以及js面试闭包完美回答 的相关内容,希望能够帮到您。