JavaScript闭包和立即执行函数的个人笔记

一、闭包

当一个内部函数被调用,就会形成闭包,闭包就是能够读取其他函数内部变量的函数。阅读下面函数思考

function a(){
	function b(){
		var bb = 234;
		console.log(aa);
	}
	var aa = 123;
	return b;
}
var glob = 100;
var demo = a();
demo();

当a函数被定义时,预编译产生全局变量GO:
在这里插入图片描述
当a函数要执行时,执行前一刻(预编译产生局部变量AO):
在这里插入图片描述
a函数执行后销毁自己的AO,回到被定义的状态
在这里插入图片描述
之后b函数被定义在a函数的环境内,预编译产生全局变量GO(可以这样理解,相对于b来说,此时它的GO是a执行时的AO):
在这里插入图片描述
然后b被保存到了外部,但身上保存了a的劳动成果
在这里插入图片描述
例:

function a(){      //a defined     a.[[scope]]- 0:GO
   function b(){   //a doing       a.[[scope]]- 0:AO; 1:GO 
      function c(){//b defined     b.[[scope]]- 0:aAO; 1:GO
	  };
      c();         //b doing       b.[[scope]]- 0:bAO; 1:aAO; 2:GO
   };
   b();            //c defined     c.[[scope]]- ......
};
a();               //c doing       c.[[scope]]- 0:cAO; 1:bAO; 2:aAO; 3:GO

所以内部被保存到了外部,必定生成闭包。闭包会导致原有作用域链不释放,造成内存泄漏(被占用)

二、闭包的作用

1.累加器的应用

function add(){
	var count = 0;
	function demo(){
		count ++;
		console.log(count);
	}
	return demo;
};
var counter = add();
counter();
counter();

函数每被调用一次。实现一次累加。
在这里插入图片描述
2.缓存应用
obj保存着两个函数被return返回到了外部。

function eat(){
	var food = "";
    obj = {
    	eater : function (){
        	console.log("I'm eat "+food);
            food = "";
        },
        push: function (myfood){
            food = myfood;
        }
    }
    return obj;
}
var eater1 = eat();
eater1.push("饭");
eater1.eater();

food在这里相当于一个隐式的存储结构。
在这里插入图片描述

三、闭包形式

  1. return形式
function a(){
     function b(){
     }
     return b;//利用return将b函数返回
};
var demo = a();
  1. 变量形式
var demo;
function a(){
	function b(){
	}
	demo = b;
}
a();
demo();

只要将内部函数被保存到外部就可以形成闭包,形式多样

四、立即执行函数

1.立即执行函数的两种常见形式

1.(function(){ }())w3c显示这种好
2.(function(){ })()
例:

var num = function (a,b,c){
		var d = a+ b + c;
		return d;
	}(1,2,3));//初始化后抛回

只有表达式才能被执行符号执行

var test = function(){
	console.log("a");
}();//函数体后面要有小括号(),函数体必须是函数表达式而不能是函数声明
!function test(){
	console.log('a');
}();//(),!,+,-,=等运算符都能起到立即执行的作用,这些运算符的作用就是将匿名函数或函数声明转换为函数表达式

立即执行函数执行后放弃函数名字(即失去索引,成为一次性的),再输出test为undefined

2.特殊情况

function test(a,b,c){
	console.log(a+b+c);
}
(1,2,3);//该形式会被读成下面写法
function test(a,b,c){
	console.log(a+b+c);
}(1,2,3);//改写法既不报错,也不执行

五、使用环境

1.例

function test(){
	var arr = [];
	for(var i = 0;i < 10;i ++){
		arr[i] = function (){
			console.log(i);
		}
	}
	return arr;
}

我们原意是写一个数组能够输出它自己的索引,但实际情况是:
在这里插入图片描述
在这里插入图片描述
因为js在进行预编译时,只是arr[i]=函数(被没有访问内部),然后i++到10时退出循环,导致真正执行时i=10。
解决方法
利用立即执行函数

function test(){
	var arr = [];
	for(var i = 0;i < 10;i ++){
		(function (j){
			arr[j] = function (){
				console.log(i);
			}
		}(i));
	}
	return arr;
}

注:闭包和立即执行函数,不会互相污染变量。

六、小练习

var x = 1;
if(function f(){}){
	x += typeof f;
	console.log(x);
}

答案和解析下一期揭晓!

博主开始运营自己的公众号啦,感兴趣的可以关注“飞羽逐星”微信公众号哦,拿起手机就能阅读感兴趣的博客啦!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

飞羽逐星

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值