首页 > 技术文章 > 20170713_js闭包/匿名函数/作用域

tiantian123 2017-07-13 18:34 原文

js:闭包
var getNum;
function getCounter() {
var n = 1;
var inner = function () {return n++; }
console.log(n);
return inner;
}
//第一步
getNum = getCounter();

//第二步
console.log(getNum());//1

//第三步
console.log(getNum());//2

//也许是这样?可能的情况1:
//第一步 getNum指向了getCounter函数的返回值,即inner函数,此时inner内的n调用的是上级函数的n,
但是没有执行,所以此时n是1,而且由于他调用的是上级函数的变量,此时inner的n突破了作用域,n=1写入到了内存中,可以以后进行调用
//第二步 执行getNum函数,也就是执行了inner函数,inner函数此时返回n++,也就是 1++ 返回了1,执行后n现在等于2了
//第三部 同上返回2,执行后n等于3
 

//或者是这样?可能的情况2:
//第一步 getNum指向了getCounter函数的返回值,即inner函数
//第二步 执行了getNum函数,也就是执行了inner函数,由于他在一个高阶函数getCounter内部,
他可以使用高阶函数内的变量n,由于inner函数被return,此时n实现了越狱,n=1写入到了内存中,可以以后进行调用,此时输出1,n++后n=2
//第三步 由于n实现了越狱,输出2,n++后n=3

//n不是全局变量,只能在inner内使用
 
//20170714_10:36更新,情况1是错误的
//第一步getNum被赋值时,inner并没有被执行,
//第二步inner执行时调用了上级函数的变量n,n最终值为1,故此时n为1然后再++,
//第三步inner查找n时n=2,然后n++,
//如果此时调用getCounter()的话.n重新被赋值为1.划重点→但是!inner里面的n不会被覆盖为1,这个inner里面的n取得于getCounter,运行于inner,不被外部函数重写,只能在自己函数的作用域内进行操作!
 
这个又涉及到了函数初始化和函数运行的问题 举个栗子
function createFunctions(){
var result = new Array();
for (var i=0; i < 10; i++){
result[i] = function(){
return i;
};
}
return result;
}
var funcs = createFunctions();
for (var i=0; i < funcs.length; i++){
console.log(funcs[i]());
}
 
//密集地雷预警
//这里输出的是10个10
//第一步creatFunctions执行后,返回的是result,返回前执行了10次for循环,对result进行赋值,result[0]=function(){return i;(此时i=0)}; ... result[9]=function(){return i;(此时i=9)};
i=9循环完成后继续for循环,此时(i=10;i<9;i++)不成立结束了for循环,也就是说creatFunctions里最终情况i=10.
//第二步for循环了funcs.length次,funcs是数组,长度为10,然后输出funcs[i](),这里有()表示执行,也就是funcs[0]()...funcs[9],看样子要返回0..9了,
然后return i;然而此时匿名函数里的i是10,也就是return 10;了10次!!!
 
20170714_11:34再更 ↑面的感觉还是有点错误
 
result[i] = function(){
return i;
}
//chrome调试时图片↓
//执行到funcs[2]时i=2,funcs[2] = function(){return i;}; 此时i=2,此时funcs[2]()并没有运行,只是显示了funcs[2]
 
 
//执行到funcs[2]()时,匿名函数被运行了,i=2被匿名函数存储的i=10覆盖,然后return i;时return了10!!!
//这次没问题了,李菊福!!!
 
 
 
//20170714
 
参考文档:
①图解JS闭包 https://zhuanlan.zhihu.com/p/27857268
②JavaScript之作用域与闭包详解http://www.cnblogs.com/syfwhu/p/4839562.html
③一分钟理解js闭包_javascript技巧http://www.jb51.net/article/83524.htm
④变量作用域http://www.liaoxuefeng.com/wiki/001434446689867b27157e896e74d51a89c25cc8b43bdb3000/0014344993159773a464f34e1724700a6d5dd9e235ceb7c000

推荐阅读