JS匿名函数和闭包

$(function() {}) 是$(document).ready(function()的简写, 这个函数什么时候执行的呢?
答案:DOM 加载完毕之后执行。

立即执行函数(function(){})()属于匿名函数,并且优先于$(function() {})加载

很多JS加载文件都装在这样的匿名函数内

1.  {(function(window, undefined) {  2.      //do something  3.  })(window);

1首先,(function(window, undefined) {})(window)可以简化看成这样()();而()()就是一个匿名函数自执行的写法.

当然(function() {})(window)好像也更加精简.后面的圆括号中的window为实参,接受window对象(window对象是全局环境下的),
2而function后面的圆括号中的window为局部变量,不是全局的window对象.所以这样写可以提高js性能,减少作用域链查询时间.(如果在函数体内多次使用到window对象,那么把window对象当着实参穿进去,是十分必要的;如果函数内部不需要,那么就无需传递该参数.);
3.function后面的形参undefined又有什么用呢?其实在一些老的浏览器中,undefined不被支持,直接使用会导致错误,所以考虑兼容性,就增加一个形参undefined;
4.(function() {})()主要用于存放开发插件的代码,执行其中的代码时DOM不一定存在,所以直接自动执行DOM操作的代码,请放心使用;

//普通函数 function box(){     return 'lee';};
//把匿名函数自我执行的返回值赋值给变量var b=function(){  //单独的匿名函数,是无法执行的 就算执行也无法调用    return 'lee';};
// 匿名函数自我执行(function (){                        //(匿名函数)(); 第一圆括号放匿名函数,第二个圆括号执行    return 'lee';            //()表示执行})();alert((function (){    return 'lee';})());
//自我执行匿名函数的传参alert((function(age,name){    return age+name;})(100,200));

匿名函数最大的用途是创建闭包(这是JavaScript语言的特性之一),并且还可以构建命名空间,以减少全局变量的使用。闭包是指有权访问另一个函数作用域中的变量的函数,创建闭包的常见的方式,就是在一个函数内部创建另一个函数,通过另一个函数访问这个函数的局部变量。

//函数里的匿名函数(闭包)function box(){    return function(){           //闭包        return 'lee';}};alert(box()());     //box()  返回是匿名函数的结构    box()()返回函数中匿名函数的返回值

闭包是指有权访问另一个函数作用域中的变量的函数,创建闭包的常见的方式,就是在一个函数内部创建另一个函数,通过另一个函数访问这个函数的局部变量。

//通过闭包可以返回局部变量function box(){    return function(){                    //通过匿名函数返回box()局部变量        return 'Lee';    };};alert(box()());                    //通过box()()来直接调用匿名函数返回值var b=box();            alert(b());                        //另一种调用匿名函数返回值

使用闭包有一个优点,也是他的缺点;就是可以把局部变量留在内存中,可以避免使用全局变量。(全局变量污染导致应用程序不可预测性,每个模块都可调用必将引来灾难,所以拓建使用私有的,封装的局部变量)

//全局变量累加// var b=100;// function box(){//         b++;// };// alert(b);// box();// alert(b);//使用匿名函数实现局部变量驻留内存中从而累加function box(){    var age=100;    return function(){        age++;        return age;    };};var b=box();alert(b());                        //每次都要匿名函数alert(b());alert(b());alert(b());//循环里的匿名函数的取值问题1function box(){    var arr=[];    for(var i=0;i<5;i++){        arr[i]=function(){            return i;        };        };    return arr;};var b=box();for(var i=0;i<5;i++){    alert(b[i]());        //这么写取值返回的都是5}//循环的匿名函数取值问题2function box(){    var arr=[];    for(var i=0;i<5;i++){        arr[i]=(function(num){            //通过自我及时执行匿名函数            return num;        })(i);        };    return arr;};var b=box();for(var i=0;i<5;i++){    alert(b[i]);        //这么写取值返回的都是5}//循环里的闭包的取值问题3function box(){    var arr=[];    for (var i =0; i<5;i++) {        arr[i]=(function(num){            //arr【0】=0,arr[1]=1,arr[2]=2.......            return function(){            //闭包可以将变量驻留到内存中。                return num            };        })(i);    }    return arr;};var b=box();for(i=0;i<5;i++){    alert(b[i]());};

内存泄漏

  由于IE的JScript和DOM对象使用不同的垃圾收集方式,因此闭包在IE中会导致一些问题,就是内存泄漏的问题,也就是无法销毁驻留在内存中的元素,以下代码有连个知识点还没有学习到,以个是DOM,一个是事件

function divShow(){    var b=document.getElementById("di");      //b  用完之后会一直驻留到内存中    b.onclick=function(){        alert(b.innerHTML);      //这里用b导致内存泄漏    };}divShow();

模仿块级作用域

  javascript没有块级作用的概念

//块级作用域(私有作用域)function box(count){    for(var i=0;i<count;i++)    //i不会因为离开了for块就失效        var i;                    //就算重新声明,也不会前面的数据        alert(i);               };box(2);

  以上两个例子,说明javascript没有块级语句的作用域,if(){}  for(){} 等没有作用域,如果有,出了这个范围:就应该被销毁了,就算重新声明同一个变量也不会改变他的值。

  javascript不会提醒你是否多次声明了同一个变量:遇到这种情况,它只会对后续I的声明视而不见(如果初始化了,当然还会被执行)使用模仿块级作用域可避免这个问题。

//模仿块级作用域(私有作用域)function box(count){    (function(){      //包含自我执行函数,就可以实现私有作用域        for(var i=0;i<count;i++)           alert(i); })();    alert(i);    //报错,无法访问  被销毁了    };

   使用了块级作用域(私有作用域)后,匿名函数中定义的任何变量,都会在执行结束时被销毁,这种技术经常在全局作用域中被用在函数外部,从而限制向全局作用域中添加过多的变量和函数,一般来说,我们都应该尽可能少像全局作用域中添加变量和函数,在大型项目中,多人开发的时候,过多的全局变量和函数很容易导致命名冲突,引起灾难性的后果,如果采用块级作用域(私有作用域)每个开发者既可以使用自己的变量,又不必担心搞乱全局作用域。

私有变量

  javascript没有私有属性的概念,所有的对象属性都是共有的,不过,却有一个私有变量的概念,任何在函数中定义的变量,都可以认为是私有变量,因为不能再函数的外部访问这些变量

function box(){    var b=100;            //私有变量,外部无法访问};

而通过函数内部创建一个闭包,那么闭包通过自己的作用域链也可以访问这些变量,而利用这一点,都可以创建用于访问私有变量的公有方法

//对象共有化function Box(){    this.age=100;                    //属性,共有的    this.run=function(){            //方法,共有的        return '运行中....';    }};var box=new Box();alert(box.age);           //返回100alert(box.run());        //返回运行中//私有化function Box(){     var age=100;                    //私有属性    function run(){                    //私有方法        return '运行中';    };    this.publicGo=function (){        //对外可见的公共接口,特权方法        return age+run();    };};var box=new Box();alert(box.age);                    //返回 undefined   找不到alert(box.run());                //返回 undefined   找不到alert(box.publicGo());            //返回 100 运行中//通过构造函数传参function Box(value){    var age=value;    this.getAge=function(){        return age;    };};var box=new Box('杜伟');alert(box.getAge());

什么叫单例:就是永远只实例化一次,其实就是字面量对象声明方式(无法第二次实例化就叫单例)。

模块模式

var box={                //这样写其实已经实例化了    age:100,    run:function(){                    return '运行中';    }};alert(box.age);    //直接就可以调用alert(box.run());//字面量私有化var box=function(){    var age=100;                //私有变量    function run(){                //私有函数        return '运行中....';    };    return {                    //返回对象        publicGo:function (){    //对外公共接口的特权方法            return age+run();        }    };}();alert(box.publicGo());

字面量的对象声明,其实在设计模式中可以看作是一种单例模式,所谓单例模式,就是永远保持对象的一个实例

(0)

相关推荐

  • 闭包理解

    闭包 刚学过的闭包,分享一下闭包的理解 1.什么是闭包? 闭包就是一个函数,也可以说闭包是一个引用关系,可以理解为一个作用域可以访问另一个函数的局部变量. 代码: function fn() { va ...

  • 程序猿 | JavaScript 闭包拆讲

    JavaScript的变量有两种,一种是局部变量,一种是全局变量. 顾名思义: 局部变量定义在函数内部,只能在函数内部访问,其他的函数无法访问: 全局变量则定义在函数外部,函数也可以访问外部变量: 二 ...

  • JavaScript——函数

    一.函数的定义与调用(与python类同)  // 无参函数 function f1() { console.log("Hello world!"); }; f1(); // 有参 ...

  • JavaScript 基础二

    函数 函数:函数就是封装了一段可以重复执行的代码块. function fn(){ console.log('我是函数') } fn(); function getSum(a,b){ return a ...

  • JavaScript 之 作用域

    学习目标:能够说出Javascript的两种作用域 能够区分全局变量和局部变量 能够说出如何在作用域链中查找变量的值 1.作用域 <script> //1.javaScript作用域:就是 ...

  • javascript中的闭包这一篇就够了

    前端技术优选 今天 以下文章来源于程序员成长指北 ,作者koala 程序员成长指北专注 Node.js 技术栈分享,从 前端 到 Node.js 再到 后端数据库,祝您成为优秀的高级 Node.js ...

  • JS自执行函数,匿名函数

    自执行函数 先来看个最简单的自执行函数 (function(){ }()); 相当于声明并调用 var b=function () { }b() 自执行函数也可以有名字 function b(){ . ...

  • Power Query里的匿名函数是什么鬼?这个例子最典型了。

    小勤:我现在有个按营业额不同等级的提成比例表,怎么用Power Query读到营业额数据表里?如下图所示: 大海:这个问题如果是在Excel里的话,用Lookup函数非常简单. 小勤:这我知道啊,但我 ...

  • [js] 第93天 js的函数有哪几种调用形式?

    今日试题: js的函数有哪几种调用形式? 此开源项目四大宗旨:勤思考,多动手,善总结,能坚持 <论语>,曾子曰:"吾日三省吾身"(我每天多次反省自己). 前端面试每日3 ...

  • 收藏,日常必备的JS工具函数大全

    Vue中文社区 昨天 来源:https://github.com/Wscats/CV/issues/27 为元素添加on方法 .. ..;.. (event, fn) {. [][].(this, ( ...

  • 在PHP中如何为匿名函数指定this?

    在PHP中如何为匿名函数指定this? 在之前的文章中,我们已经学习过匿名函数的使用,没有看过的小伙伴可以进入传送门先去了解下闭包匿名函数的用法,传送:还不知道PHP有闭包?那你真OUT了. 关于闭包 ...

  • [PHP小课堂]在PHP中如何为匿名函数指定this?

    [PHP小课堂]在PHP中如何为匿名函数指定this? 关注公众号:[硬核项目经理]获取最新文章 添加微信/QQ好友:[xiaoyuezigonggong/149844827]免费得PHP.项目管理学 ...

  • Python中的匿名函数

    原创 DBA随笔 DBA随笔 1周前 // Python中的匿名函数 // 写python的时候,大多数场景下,我都是if else选手,因为最核心的逻辑几乎都是通过if else语句来实现的.关于匿 ...

  • 匿名函数没有自己的this

    匿名函数没有自己的this,因此,在构造对象中调用全局函数时,可以省去保存临时this,再将其传入全局函数这一步: 1 <!DOCTYPE html> 2 <html lang=&q ...

  • JS的函数方法:call() apply() bind() 自定义绑定对象

    把方法绑定到对应的对象上,那么该对象就不用再重写一遍相同的方法了,这样就达到了重复利用的目的. 一.bind方法 使用bind重新绑定对象. function foo() { console.log( ...