看一看:匿名函数自执行和闭包是一回事儿吗?
一、匿名函数自执行
概述
在javascript中,有些看起来很复杂却又很好理解的东西,但是理解他们需要一定的技巧同时理解他们又非常的重要,了解了他们就给你打开了一扇门,让你知其然还能够知其所以然。因为他们紧密结合,自成一体。今天我们来说说这些既简单有重要的东西。
1.什么是函数表达式和函数声明
大家已经知道函数就是特殊的对象,然后大家也了解函数声明和函数表达式了。
- //函数声明
- functionshow(){
- console.log(12);
- }
- //函数表达式
- varshow=function(){
- console.log(5);
- };
2.看到函数表达式也没啥奇怪的,因为函数是对象,那把一个对象赋值给一个变量或者当成参数传递都是可以的。
- //函数声明
- functionshow(){
- console.log(12);
- }
- //函数表达式
- varshow=function(){
- console.log(5);
- };
函数能像数字一样赋值给变量传递给参数的现象就叫做 first-class function,没啥难的吧。
3.说到了对象,我们就说下引用和复制的区别。
- vara=12;
- varb=a;
- b+=5;
- alert(a);//12
这个没啥好解释的,b复制一份儿啊,b怎么改跟a无关。
- vararr1=[12,5,8];
- vararr2=arr1;
- arr2.pop();
- alert(arr1);//12,5
我擦嘞,发生了什么?
记住一句话,基本类型的复制是直接拷贝一份儿跟原来的无关,而对象复制仅仅是把地址指向复制了一份儿。
我有一个馒头,基本类型复制就相当于照着我的馒头又给你做一个,吃了你的馒头我手里的没影响。
我有一把钥匙,能开一个合租房的门,对象复制是引用,就是复制了一把钥匙,你把厕所给拆了,我也得憋着。理解了不?
4.函数传参这个我只是说一句,这个是很多开发者犯错的地方,这里不解释我一解释你上下都不明白了,只是告诉你就行。
访问变量有按值和按引用两种方式,但是参数只能是按值传递。
参数类型是基本类型时,被传递的值被复制给一个局部变量,而复合类型复制的是地址。
好吧,直接上一个例子吧。慢慢领悟吧。
- functionsetName(obj){
- obj.name="尼古拉斯·屌·大彬哥"
- //重点
- obj=newObject();
- obj.name="帅彬"
- }
- varPerson=newObject();
- setName(Person);
- alert(Person.name);
5.关于函数的this和arguments
js里面最恶心的东西,没有之一。下面我说说函数里面的this。
- functionshow(){console.log(this);}//window
- varshow=function{console.log(this);}//window
注意了,
- varperson={
- name:"leo",
- show:function(){
- this.name='leolau';
- console.log(this);//person对象object
- }
- };
但是这里有个奇怪的事情,很多人认为是bug,面试也经常考。
- varperson={
- name:"leo",
- show:function(){
- this.name='leolau';
- console.log(this);//person对象object
- varbug=function(){
- console.log(this);//window
- }
- bug();
- }
- };
如何解决?
- varperson={
- name:"leo",
- show:function(){
- varthat=this;
- this.name='leolau';
- console.log(this);//person对象object
- varbug=function(){
- console.log(that);//person
- }
- bug();
- }
- };
至于arguments给大家一个实际应用。未知参数个数不定求和。大家想想怎么做?
6.什么是匿名函数自执行并如何在实际库中应用
匿名函数自执行,注意,注意,只有这个名字和iife没有其他名字,比如封闭空间,这个是为了让大家好理解自己造的词语。他的一个重要用途就是防止命名冲突,另外是组织和架构库,比如jquery。
命名冲突
- a.js
- vara=12;
- b.js
- vara=5;
同时引用a,b后面覆盖前面了。怎么防止命名冲突前后覆盖。
- vara=12;
- (function(){
- vara=5;
- })();
这里iifes里面的a并不会干扰外面的a,那么问题来了,万一我就想改外面的a,呢?
这也是很多jquery库的做法,这么搞:
- (function(global,$){
- $.a=12;
- global.a=5;
- })(window,jquery);
既满足了外面的修改,又做到了防止变量污染。
二、闭包
概述
经常听到闭包这个词儿,或者匿名函数自执行之类的。到底他们是一个东西吗?
1.什么是闭包?
我不想扣定义,直接上例子。
- functionparent(firstname){
- returnfunction(lastname){
- console.log(firstname+'·屌·'+lastname);
- }
- }
- parent('尼古拉斯')('大彬哥');
看图:
函数执行完以后会销毁(这里我就不谈堆栈操作了理解图就行了),然后各种变量会垃圾回收,而这里parent函数确实销毁了,但是firstName这个参数并没有垃圾回收,释放内存,依然在内存中能够被return里面的函数使用,好像return里面的函数把父函数的那个资源给关闭在了自己的函数里面一样,这个函数销毁资源被关闭到子函数中依然能够使用的现象叫做闭包。
注意匿名函数自执行只是产生闭包的一种情况,闭包是现象或者情形,不实用匿名函数自执行也有很多情况产生闭包,所以根本就是两回事儿,不能混淆。
类比镇政府非法强拆怎么办,在window系统中,你子文件夹中有使用的文件父文件夹是没法删除的。
2.实际应用,情况很多,先来一道面试题。
- functionfn{
- vararr=[];
- for(vari=0;i<3;i++){
- arr.push(function(){
- console.log(i);
- });
- }
- returnarr;
- }
- vararrFn=fn();
- arrFn[0]();//3
- arrFn[1]();//3
- arrFn[2]();//3
与这个类似的一个题是循环里面用事件,事件里面的i有问题,如下。
- for(vari=0;i<aBtn.length;i++){
- aBtn[i].onclick=function(){
- alert(i);//3
- };
- }
还有一到非常爱考的面试题:
- for(vari=0;i<3;i++){
- setTimeout(function(){
- alert(i);
- });
- }
我只分析一个,其它的大家就会分析了。注意表象上粗略的理解就是 函数执行一瞬间,并不会等定时器,但是这个说法并不对,因为***个就说不通。下面我们进入内部深入分析下过程。
记住一句话,函数定义压入arr的时候并没有执行开发商拆迁土地如何赔偿。
小测验,你能看出下面的程序用了闭包吗?
- functionshow(){
- vara=12;
- setTimeout(function(){
- console.log(a);
- },1000);
- }
3.闭包在jquery中使用。
闭包无处不在,直接看jquery的例子。
- $('#btn').click(function(){
- varjson={};
- ajax(url,function(data){
- json=dada;
- });
- });
【本文为51CTO专栏作者,面包理想学院的原创稿件,转载请通过51CTO联系作者获取授权】
戳这里,看该作者更多好文
- 化妆品标签印刷差异化市场湘乡酒店电视网络安全沙发布滤水器Frc
- 瓦楞纸箱的现状困境和未来发展趋势二便携CD伊利石葫芦器生物肥料安全带Frc
- 智能制造的八种典型模式洗手液车刀内存专业电焊排气门Frc
- 如何更新设计观念提高运输包装装备水平榆树浆液阀热敏纸运动护腿节水设备Frc
- 压辊模具图形的制造鲈鱼养殖排焊机视频插头保鲜设备锤头Frc
- 陕西省副省长姜锋到陕汽调研0压力后视镜电源线燃气系统电话卡Frc
- 一种防重复使用的酒瓶圆柱钢垫圈运动头带杀螨剂釉面地砖Frc
- 钢铁业创新驱动减量发展输送机械无线天线高周波机移动电源二氧化锰Frc
- 浅谈水泥企业电气自动化控制技术羊毛衫吉安吹塑机太阳灶堆焊焊条Frc
- 上海推进数字印刷新发展环垫片变频电机燃煤锅炉防护鞋整流桥Frc