javascipt之匿名函数和闭包

匿名函数

匿名函数的几种形式

function (){        //基本匿名函数,会报错
return 'Lee';
}


(function box(){    //通过表达式自我执行
alert('Lee');
})();               //()表示执行函数,并且传参

var box = function () { //将匿名函数赋给变量
return 'Lee';
};
alert(box());       //调用方式和函数调用相似


function box () {
return function () { //函数里的匿名函数,产生闭包
return 'Lee';
}
}
alert(box()()); //调用匿名函数

闭包

当在一个函数中定义另一个函数时,就会产生闭包。内层函数和外层函数所包含的局部变量(即外层函数的上下文变量)构成闭包。使用闭包有一个优点,也是它的缺点:就是可以把局部变量驻留在内存中,可以避免使用全局变量。
使用闭包实现变量的累加,

function plus() {
    var temp=100;
    return function(){
        temp++;
        return temp;
    }
}
var p=plus();   //变量p指向函数plus

alert(p()); 
alert(p());

循环里包含匿名函数:

function loop(){
    var arr=[];
    for (var i = 0; i < 5; i++) {
        arr[i]  = function(){
            return i;
        };

        }
    return arr;
    }
    var lo =loop();
    alert(lo.length); #显示5
    for (var i = 0; i < lo.length; i++) {
        alert(lo[i]());
    }
    #首先看loop函数的返回值,lo[0]存储的是function(){return i},同理lo数组中其他几个值存储的也应该是相同的值,当loop函数返回值的时候,此时的i已经变成了5,而返回值中存储的却是i,所以当我们使用lo[i]()对它们分别进行打印时,值都是5

现在将以上代码改为自我执行的匿名函数。

function loop(){
    var arr=[];
    for (var i = 0; i < 5; i++) {
        arr[i]  = (function(num){
            return num;
        })(i);

        }
    return arr;
    }

    var lo =loop();

    for (var i = 0; i < lo.length; i++) {
        alert(lo[i]);
    }
    #此时输出为0,1,2,3,4.当loop函数进行第一次循环时,此时arr[0]的值为匿名函数的返回值,而不是上例中匿名函数本身,所以返回了我们想要的结果
闭包和this对象

this 对象是在运行时基于函数的执行环境绑定的,如果this 在全局范围就是window,如果在对象内部就指向这个对象。而闭包却在运行时指向window 的,因为闭包并不属于这个对象的属性或方法。

var user = 'The Window';
var obj = {
user : 'The Object',
getUserFunction : function () {
return function () { 
return this.user;
};
}
};
//闭包不属于obj,里面的this 指向window,所以返回值为The window
作用域
for (var i=0; i<2; i++) {}
alert(i);
#在其他语言中,解释器可能会提示i未声明,但在js中因为没用块级作用域,所以会输入2,

虽然在{}中没有块级作用域,但是js可以通过自我执行的匿名函数来实现

(function () {
for (var i=0; i<2; i++) {}

})()
alert(i);   
#此时将会报错,无法打印i,使用了块级作用域(私有作用域)后,匿名函数中定义的任何变量,都会在执行结束时被
销毁

私有变量:任何在函数中定义的变量,都可以认为是私有变量,因为不能在函数的外部访问这些变量。上例中,通过自我执行的匿名函数实现的块级作用域就时通过这种方式。
为了使外部可以访问私有变量,

var name =222;
function Box() {
var age = 100; //私有变量
var name = 111;
function run() { //私有函数
return '运行中...';
}
alert(this.name)
this.get = function () { //对外公共的特权方法
return age + run();
};
}
Box();
alert(this.get());
#此时打印的值为222,所以此函数中的this指向的是window对象,然后我们通过在此函数中将匿名函数赋给Window对象属性的方式来获得私有变量。
#将会输出100运行中...,
#如果我们将调用方式改为
var box = new Box();
alert(box.get());
#此时的name值将是udifend的,而get输出则正常,var box = new Box();执行此行代码时,我们创建了一个对象,此时Box中的this将指向此对象,而这个对象中是没有name属性的,它只有get这一个属性,在函数声明时的var name=111;是函数的属性,并不是对象的属性,
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值