JavaScript闭包
栏目: JavaScript · 发布时间: 5年前
内容简介:使用js的命名空间,优点:变量不受污染。
var
// 通过变量 向外传递 var b = ''; function fn1(){ var a = "月薪10w"; b = a; } fn1(); alert(b); //取到函数内局部作用域的变量a的值 // 通过函数传参获取 function fn1(){ var a = "月薪10w"; fn2(a); } function fn2(str){ alert(str); } fn1(); 复制代码
alert(fn1); //undefined { function fn1(){ alert(1); } } 复制代码
二、闭包
- js垃圾回收机制:js 中的变量和函数不再使用后,会被自动js垃圾回收机制回收。
- 形成闭包的条件:有函数/作用域的嵌套;内部函数引用外部函数的变量/参数。
-
闭包的结果:内部函数的使用外部函数的那些变量和参数仍然会保存,使用
return
返回了此内部函数,上面的变量和参数不会被回收。 - 闭包的原因:返回的函数并非孤立的函数,而是连同周围的环境(AO)打了一个包,成了一个封闭的环境包,共同返回出来 ---->闭包。
- 我们在返回函数的时候,并不是单纯的返回了一个函数,我们把该函数连同他的AO链一起返回了。
- 函数的作用域,取决于声明时而不取决于调用时。
-
变量存储
function(){}
、{}
、[]
存储的是一个地址。
function t1(){ var age = 20; function t2(){ alert(age); } return t2; } var tmp = t1(); var age = 1000; tmp(); //20 // win 1. AO{t1:function(){},tmp:un,age:un} // 2. t1 1. AO{age:un,t2:fun} // 2. AO{age:20,t2:fn} // AO{t1:function(){},tmp:t2,age:1000} // // tmp t2 1.AO{} 复制代码
var age = 10; function t1(){ var age = 20; return function t2(){ alert(++age); } } var t3 = t1(); t3(); // 21 t3(); // 22 t3(); // 23 alert(age); //10 复制代码
var age = 10; function t1(){ var age = 20; return function t2(){ alert(++age); } } var t3 = t1(); var t4 = t1(); t3(); //21 t4(); //21 复制代码
function foo(){ var a = 2; function baz(){ console.log(a); } bar(baz); } function bar(fn){ var a = 3; fn(); } foo(); //2 复制代码
三、闭包计数器
使用js的命名空间,优点:变量不受污染。
<script> var chengming = {};//js的命名空间 一般就是这么写 chengming.inc = (function(){ var cnt = 0; return function(){ return ++cnt; } })(); console.log(chengming.inc()); </script> <script> var cnt = 100; console.log(inc()); //报错,window下访问不到inc </script> 复制代码
四、循环中的闭包
<body> <input type="button" name="" value="按钮1"> <input type="button" name="" value="按钮2"> <input type="button" name="" value="按钮3"> </body> <script> var inp = document.getElementsByTagName('input'); for(var i=0; i<inp.length; i++){ inp[i].onclick = function(){ inp[i].style.background = "yellow"; } } //点击按钮会报错,因为i在window全局上,for结束之后,本身的值就是3 </script> 复制代码
// 方法一 用自定义属性 for(var i=0;i<inp.length;i++){ inp[i].i = i; inp[i].onclick = function(){ inp[this.i].style.background = 'yellow'; } } 复制代码
// 方法一 用let关键字 for(let i=0; i<inp.length; i++){ inp[i].onclick = function(){ inp[i].style.background = "yellow"; } } 复制代码
// 方法三 使用this for(var i=0; i<inp.length; i++){ inp[i].onclick = function(){ this.style.background = "yellow"; } } 复制代码
// 方法四 for循环每次执行,都会立即执行一个匿名函数,并且匿名函数的作用域中传入了当时的i作为参数传递 for(var i=0; i<inp.length; i++){ (function(i){ // AO{i:1} inp[i].onclick = function(){ // AO:{} inp[i].style.background = 'yellow'; } })(i) } 复制代码
// 方法五 for(var i=0; i<inp.length; i++){ (function(){ // AO{} var arg = i; inp[arg].onclick = function(){ // AO:{} inp[arg].style.background = 'yellow'; } })() } 复制代码
// 方法六 for(var i=0; i<inp.length; i++){ inp[i].onclick = function(i){ // AO:{i:0} return function(){ inp[i].style.background = 'yellow'; } }(i) } 复制代码
// 方法七 for(var i=0; i<inp.length; i++){ (inp[i].onclick = function(){ inp[arguments.callee.i].style.background = 'yellow'; }).i = i; } 复制代码
// 方法八九 基本包装类型 for(var i=0; i<inp.length; i++){ inp[i].onclick = new Function(`inp[${i}].style.background = 'yellow';`); } for(var i=0; i<inp.length; i++){ inp[i].onclick = Function(`inp[${i}].style.background = 'yellow';`); } 复制代码
以上所述就是小编给大家介绍的《JavaScript闭包》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。