JavaScript闭包
一、 变量作用域
变量作用域:全局变量&局部变量
函数能访问全局变量
子函数能访问父函数变量,父函数不能访问子函数变量
如:
function f1(){
var n=999;
}
alert(n); // error
为了让父函数能获取子函数的变量,将子函数作为结果返回,此时,子函数的相关变量都保存在返回值中,子函数的内部变量也就可以被父函数引用。
function count() {
var arr = [];
for (var i=1; i<=3; i++) {
arr.push(function () {
return i * i;
});
console.log(i);
}
return arr;
}
var results = count(); // 1 2 3,function arr
console.log(results()); // results不是函数
var f1 = results[0];
console.log(f1()); // 16
var results = count()
将函数count
的返回值arr
赋给新变量results
,此时results
是个数组函数
,count()
函数执行,for
循环执行,每次循环产生一个函数,添加到arr
中,所以有 1 2 3
输出,但是arr.push
函数并没有执行;
var f1 = results[0]
将results[0]
赋值给新变量f1
,此时f1
是个函数
在console.log(f1())
时调用了f1()
,arr.push
函数才执行,但是此时i
已经变成4
,所以该步输出16
二、闭包
闭包,我的理解是:调用了局部变量的子函数即为闭包,也可上述arr.push()
即为闭包。
三、闭包的用途
- 让父函数可以获取子函数内部变量
- 让子函数变量的值始终保持在内存中
四、闭包典型例子
(1)
function test() {
var n = 999;
function add() {
n++;
console.log(n);
}
return { n: n, add: add}
}
var result1 = test();
var result2 = test();
result1.add(); // 1000
result1.add(); // 1001
console.log(result1.n); // 999
result2.add(); // 1000
(2)
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
return function(){
return this.name;
};
}
};
alert(object.getNameFunc()()); // My Object
(3)
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
var that = this;
return function(){
return that.name;
};
}
};
alert(object.getNameFunc()()); // The Window