JavaScript闭包
栏目: JavaScript · 发布时间: 6年前
内容简介:使用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闭包》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
复盘+:把经验转化为能力(第2版)
邱昭良 / 机械工业出版社 / 39.00
随着环境日趋多变、不确定、复杂、模糊,无论是个人还是组织,都需要更快更有效地进行创新应变、提升能力。复盘作为一种从经验中学习的结构化方法,满足了快速学习的需求,也是有效进行知识萃取与共享的机制。在第1版基础上,《复盘+:把经验转化为能力》(第2版)做了六方面修订: ·提炼复盘的关键词,让大家更精准地理解复盘的精髓; ·基于实际操作经验,梳理、明确了复盘的"底层逻辑"; ·明确了复......一起来看看 《复盘+:把经验转化为能力(第2版)》 这本书的介绍吧!