立即执行函数(function(){})()属于匿名函数,并且优先于$(function() {})加载 很多JS加载文件都装在这样的匿名函数内 1. {(function(window, undefined) { 2. //do something 3. })(window); 1首先,(function(window, undefined) {})(window)可以简化看成这样()();而()()就是一个匿名函数自执行的写法. 当然(function() {})(window)好像也更加精简.后面的圆括号中的window为实参,接受window对象(window对象是全局环境下的), //普通函数 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()); 字面量的对象声明,其实在设计模式中可以看作是一种单例模式,所谓单例模式,就是永远保持对象的一个实例 |
|
来自: 仴嗈鼋嗌鄦嶜 > 《javascript》