对比代码:
【代码1】:
function each(){
var i = 0, inner ,a=[];
for(;i<10;i++){
a.push(function(){
console.log(i);
})
}
return a;
}
var a = each();
for(var i = 0; i < a.length; i++){
a[i]();
}
【代码2】:
function each(){
var i = 0, inner ,a=[];
for(;i<10;i++){
a.push(function(i){
console.log(i);
})
}
return a;
}
var a = each();
for(var i = 0; i < a.length; i++){
a[i](i);
}
【代码3】:
function each(){
var i = 0, inner ,a=[];
for(;i<10;i++){
cache(i);
}
function cache(i){
a.push(function(){
console.log(i);
})
}
return a;
}
var a = each();
for(var i = 0; i < a.length; i++){
a[i]();
}
【代码4】:
function each(){
var i = 0, inner ,a=[];
for(;i<10;i++){
cache(i);
}
function cache(b){//这段代码和上一段代码比较目的在于,cache函数的参数被内部函数引用,无关参数名
a.push(function(){
console.log(b);
})
}
return a;
}
var a = each();
for(var i = 0; i < a.length; i++){
a[i]();
}
【代码6】:
function each(){
var i = 0, inner ,a=[];
for(;i<10;i++){
cache(i);
}
function cache(){
a.push(function(){
console.log(i);
})
}
return a;
}
var a = each();
for(var i = 0; i < a.length; i++){
a[i]();
}
【代码7】:
var body = document.body;
var items = ["click","mousemove"];
for(var i = 0;i<items.length;i++){
(function(){ //自运行函数开辟了一个新的域,和外层的for明显不在一个域中
var item = items[i];//但是这里每次都保存了外层的for的临时变量。
body["on"+item] = function(){
console.log(item);
}
})()
}
【代码8】:
var body = document.body;
var items = ["click","mousemove"];
(function(){
for(var i = 0;i<items.length;i++){
var item = items[i];
body["on"+item] = function(){//函数开辟了一个新的域,和外层的for明显不在一个域中,顾item引用了外层的最终值
console.log(item);
}
}
})()
【代码9】:
function User(pr){
for(var i in pr){
(function(which){
var p =i;//因为这里定义的自运行函数和外部的for语句已经不在同一个域中了,如果不保存临时的变量,那么将得到最终值
which["get"+p] = function(){
return pr[p];
};
which["set"+p] = function(val){
pr[p] = val;
}
})(this)
}
}
var u = new User({name:"louis",age:25})
alert(u.getname())
alert(u.getage())
【代码10】:
function User(pr){
for(var i in pr){
(function(which){
//var p =i;//每次for循环都会临时保存变量的值(i),但是如果这个临时保存的值这里没有被记录下来,那么内层定义的函数依旧是去找引用的变量所在的定义层(这里是自运行函数的外层函数)的最终值。所以这里i就是去找pr对象中的最后一个属性。
//这里在引用下JQuery之父的解释:闭包允许你引用父函数中的变量,但是提供的值并非该变量创建时的值,而是父函数范围内的最终值。
//所以说,判断某个函数引用的值到底是什么?需要1.判断该函数是不是定义在另一个函数体中?2.引用的值是不是外层函数定义的?
which["get"+i] = function(){
return pr[i];
};
which["set"+i] = function(val){
pr[i] = val;
}
})(this)
}
}
var u = new User({name:"louis",age:25})
alert(u.getname())
alert(u.getage())
【Tips】:
函数的闭包,一定要定义在某个函数内部,才能获得这个函数的变量的最终值!
【总结】:
个人理解,闭包其实就是连接函数内部世界与外部世界的一个桥梁。作为闭包,首先,闭包所在父函数的内部的私有成员,肯定是不能直接被外部访问的。外部要访问闭包所在的父函数内部的成员,就需要提供一个接口,闭包就担任这个任务!所以可以理解其为一个桥梁,一端是函数内部的封闭世界,另一段是外部的操作。大家也可以理解闭包所在的父函数就像是一个黑匣子,闭包就是提供对外的一个接口了。
1398

被折叠的 条评论
为什么被折叠?



