JavaScript之----匿名函数、闭包

时间:2021-09-26 19:15:02
匿名函数
匿名函数就是没有名字的函数
(function () {     alert("匿名函数()"); })
//匿名函数的调用
(function () {    alert("匿名函数()");})();

(function (name) {    alert(name);})("lisi");
var s = (function (name) {
    return name;})("zhangsan"); alert(s);   //zhangsan
alert( (function (name) {    return name;})("zhangsan"));
//把匿名函数赋值给一个变量 var m = function(){         alert("ha"); }; m();  //ha
var b = function(name){        alert(name);};b("xiaoli");  
var a = function(name){        return name;};alert(a("xiaoli"));  
闭包 1定义:在一个函数内部创建另一个函数,通过另一个函数访问这个函数的局部变量。
function show(){         var name = "lisi";         return function(){                 return name;             };                                           //闭包  这个函数是个引用类型的对象,所以可以用一个变量接收一下 如① } var fun = show();       ① fun();  //就是在调用紫色部分那个函数
或者:show()();     这也是在调用紫色部分函数
2好处: 例:实现一个变量的累加 function add(){     var age = 10;     age++;     return age; } alert(add());//11 alert(add());//11解释:每次调用add函数时会给age开辟内存,结束时释放内存,函数每次调用时,局部变量开辟内存,函数调用结束时,局部变量释放内存。
局部变量不能实现每次调用age++,解决这个问题可用全局变量,但是全局变量是公共的,任何函数都可以使用,容易出现问题,所以尽量少用全局变量,为了解决这个问题,让age的值逐渐递增使用闭包。
function add1(){    var age = 10;    return function(){        age++;        return age;    };}var func = add1(); alert(func());//11 alert(func());//12而
alert(func());//13    
解释:反复调用的是func(),add1()只调用了一次;闭包使用的局部变量,不会立刻释放内存,会在内存驻留一段时间。 注意:尽量少使用闭包,在必要时再使用闭包
3在循环中使用闭包:

function fun(){     var arr =[];     for(var i = 0;i<3 ; i++){         arr[i] =function (){                 return i;         };     }     return arr; } var a = fun(); for(var j = 0; j<a.length; j++){     alert(a[j]());          //a[j]  代表的是一个函数  调用这个函数a[j]()  运行后显示是 3 3 3  } JavaScript之----匿名函数、闭包

function fun(){    var arr =[];    for(var i = 0;i<3 ; i++){        arr[i] =(function (num){                return num;        })(i);              //改成了函数调用,当i= 0 时,num = 0,返回0放在arr[0]中    }    return arr;}var a = fun();for(var j = 0; j<a.length; j++){    alert(a[j]);          //012}
//用闭包实现如下: function fun(){    var arr =[];    for(var i = 0;i<3 ; i++){        arr[i] =(function (num){                return frunction(){                            return num;                        };        })(i);           }    return arr;}var a = fun();for(var j = 0; j<a.length; j++){    alert(a[j]());          //012    闭包中的局部变量会长时间驻留,所以 012都不会立刻消失}
4闭包中this的特点 闭包中的this在运行时指向windw,因为闭包并不属于这个对象的属性或方法。
var obj ={     name:"lisi",     fun:function(){         return function(){                 return this;         };     } }; var a = obj.fun(); a();    //返回的this指向的是window
var name = "window";
var obj2 ={    name:"object",    fun:function(){        return function(){                return this.name;        };    }};alert(obj2.fun()());         //window
alert(obj2.fun().call(obj2) );  //对象 冒充   显示  object   

var name = "window";
var obj2 ={    name:"object",    fun:function(){            var t = this;   //obj2        return function(){                return t.name;    //引用之间的赋值        };    }};alert(obj2.fun()());         //object
5块级作用域 js中不存在块级作用域   if(){}   for(){} 实现for循环结束时,变量i的作用域结束,i在内存中消失 //模拟块级作用域(私有作用域) (function () {         //作用域 })(); //在之后做项目中会经常用到,在项目中,尽量少使用全局的变量和函数,多用块级作用域
function fun(){     (function(){          for(var i = 1; i<=3;i++){                alert(i);        } })();   //匿名函数执行完时(i相当于其中的局部变量,)i的作用域结束,从内存中释放了 alert(i);        //访问不到了 } fun();
6私有变量、静态私有变量 (1)私有变量
function show(){     var num = 5;                           //私有变量(局部变量)     function test(){                        //私有函数(局部函数)         return "我是局部函数";     }     this.test = function(){         return num + test();     } } var s = new show(); s.test();                                           //可以通过公共的访问私有的
function Test(){         this.name ="lisi";                //公共属性         this.fun = function(){         //公共函数             alert(this.name);         } }                                                    (这是一个构造函数) var t1 = new Test(); alert(t1.name); t1.fun();

//使用构造函数的传参访问私有变量
function Person(value){     var user = value; //私有变量     this.getUser = function(){       //公共的         return user;     } this.setUser = function(v){         user = v;     } }
var person = new Person("hello"); alert(person.getUset()); person.setUser("hai"); alert(person.getUset());

(2)静态私有变量:所有对象共享的局部变量(在内存中只有一块)
//让一个私有变量,被所有对象共享
//块级作用域 (function(){     var country = '';         //静态私有变量 //这是一个全局的Person         Person = function(value){                 country = value;             }
        Person.prototype.setCountry = function(c){           //提到共享应想到原型                country = c;            }                   Person.prototype.getCountry = function(){                          return country;            }                                 })();
var ren = new Person("usa");
var ren2 = new Person("china");alert(ren2.getCountry()); //china
alert(ren.getCountry());  //china   因为只有一个country

7访问私有变量和私有函数的其他方式
(1)块级作用域+字面量 方式访问私有变量,私有函数 var objs = (function(){     var name = "zhang";     //私有变量     function show(){             //私有函数            return “我爱编程”;         }    return  {         go:function(){                     return  name+show();                 }     }                    //字面量对象 })();        alert(objs.go()) ;     //zhang我爱编程
细节:如果块级作用域赋给一个变量,绿色小括号可以省略()
var objs = function(){    var name = "zhang";     //私有变量    function show(){             //私有函数           return “我爱编程”;        }   var o =  {        go:function(){                    return  name+show();                }    };        return o;       //这个o是个引用,指向的是这个字面量对象,最后返回的这个字面量对象}();
(2)块级作用域+构造函数 方式访问私有变量,私有函数 function Test(){}
var oo = function(){    var name = "zhang";     //私有变量    function show(){             //私有函数           return “我爱编程”;        }    var t = new Test();    t.go=function(){           return  name+show();    } return  t;             }();alert(oo.go());