众说闭包 闭包是什么?
犀牛书:函数变量可以保存在函数作用域内,从技术角度讲,所有函数都是闭包
function bar(){ let n = 0; }
高级程序设计:闭包是指有权访问另一个函数作用域中变量的函数
(函数没导出)
function foo(){ let n = 0; function bar(){ console.log(n) }; bar(); //bar就是闭包 } foo()
你不造的js: 当函数可以记住并访问所在的词法作用城时,就产生了闭包,即使函数是在当前词法作用域之外执行。
function foo(){ let n = 0; return function bar(){ //bar就是闭包 console.log(n); }; } foo()();
MDN:一个函数和对其周围状态
(词法环境)
的引用捆绑在一起(或者说函数被引用包围)
,这样的组合就叫闭包。也就是说,闭包让你可以在一个内层函数中访问到其外层函数的作用域。在JavaScript 中,每当创建一个函数,闭包就会在函数创建的同时被创建出来。
总结
参考常见形式便于理解
函数的执行,导致函数被定义;(被定义的函数可以拿到父函数的变量)
闭包和函数的定义有关
this和函数的执行方式有关
不是闭包的例子:
function foo(fn){ let n = 0; fun(); } function text(){ console.log(n); } foo(test);
闭包常见形式:
函数的返回值是函数
function foo(){ let n = function(){ } return n; //or //return function(){}; }
函数内全局定义函数
let func; function foo(){ let n = 1; func = function(){console.log(n)}; }
函数参数
let func = function(fn){ console.log(fn()) }; function foo(){ let a = 'aaa'; let n = function(){return a}; func(n) } foo(); //------------------------------------------------------------ (function(){ let a = 'aaa'; let n = function(){return a}; func(n) })()
循环赋值
function foo(){ let arr = []; for(var i =0; i<10; i++){ arr[i] = function(){ console.log(i); } } return arr; } let bar = foo(); bar[0]() //10
//不用let从零打印: function foo(){ let arr = []; for(var i =0; i<10; i++){ arr[i] = (function(j){xx console.log(j); } })(i) return arr; } let bar = foo(); bar[0]() //0