您的位置:首页 > Web前端 > JavaScript

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

2016-08-04 18:15 169 查看
匿名函数

匿名函数就是没有名字的函数
(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 
}



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());
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息