写给女友的JS教程---之JS闭包

女朋友"胖子"正在学JS, 到闭包这一块遇到了一些障碍.

我在网上帮她找了一些文章,但又写的又枯燥又长,我来写一篇简单点的吧.


从一次穿越说起-----

有姐妹俩,大桃花和小桃花相继出生,

有一次小桃花在河边洗衣服,出现奇特星像--十字连珠,小桃花穿越到了清朝.

还进宫见到了四阿哥,身边有一群宫女,和小桃花妹相称.


四阿哥问:"小桃花,你的姐姐是谁?"

小桃花怎么答?   这牵涉到一个问题----

人穿越后,对其亲人的计算,以"出生"时的环境为准,还是"当前问她"时的环境为准?


如果你回答:"以当前问她是为准",那你是"卖姐求荣"啊.大笑

如果你回答:"以她出生时为准,即回答大桃花" ----,恭喜你,你已理解了闭包.


闭包即 函数定义时,连同其定义环境的上下文,形成一个整体. 

不管该函数在哪儿运行,其对变量的访问,都要从定义处开始寻找.


例子1: 看你理解了没

function closure() {
    var sister = '大桃花';

    var mysister = function() {  
        return sister;
    }

    return mysister;   // 这个函数出生时,有一个sister 叫大桃花
}


function place() {  // 大清宫殿内

    var sister = '大福晋';
    var mysister = closure(); // 调用closure,mysister函数穿越到宫内 

    alert(mysister());

}


place(); // 清宫戏开始;

//  打印"大福晋",还是打印"大桃花"?
// 对的,"大桃花",闭包就这么简单,你已经悟了.


例子二: 再复杂一点,来个闭包计数器

如果你准备在页面内建一个"统一id号生成器",

比如为各种事件句柄,或者事件调用统一分配不重复的id,

(jquery里就有类似的应用).

---如何来做呢?


你可能说:"好办,弄个全局变量,叫count, 每次都把+1", 

全局变量可以做到,但是这种做法不够优雅,造成全局变量污染.

更坏的是这个变量,容易被别人(不小心)定义的同名全局变量给覆盖了.快哭了


怎么办? 用闭包!

// 闭包计数器
var counter = (function() {
    var cnt = 0;   
    return (function () {  // cnt和返回函数是一个闭包,
        return ++cnt;      // 除了这个函数,谁也别想影响cnt :) 
    });  // 返回一个匿名函数
})();   //立即执行匿名函数,返回值是一个函数,该函数赋给counter

alert(counter()); // 1
alert(counter()); // 2
alert(counter()); // 3


在上面的例子中, 

1:除了counter()函数,其他语句对于cnt都够不着,摸不到.

2: 匿名函数执行后,给人的感觉是----函数内的局部变量 cnt应该消失才对,

实际上没有消失----被返回的函数所捕捉,形成了一个"环境变量+函数"的包,

外界又打不进去, 所以叫闭包啊.大笑


例子三: 如何在JS的面向对象应用中,写一个私有属性?

你已经猜到了,还是用闭包.

// 闭包示爱器---JS面向对象之私有属性问题

function girl() {
    
    var love = '宝玉';  // 这是变量
    
    this.age = 19;      // 这是属性,注意对比.

    this.showlove = function() {
        return love;
    }
}

var lindaiyu = new girl();

// 想一想,在外界,谁能访问到黛玉的"age"?
// 大家都可以

alert(lindaiyu.age); // 19;

// 再想,谁能在外界访问到黛玉的"love"
// 谁也别想,除非黛玉的showlove()公有方法才能访问该值
alert(lindaiyu.showlove());



例子四: 看你确实掌握了闭包没?

// 我想创建4个函数,装在一个数组里
// 每个函数调用时,弹出不同的值
// 于是我写出这样的for循环
for(var i=0,arr=[];i<=3;i++) {
    arr.push(function(){alert(i)});
}

arr[0]();  // ?? 结果不是0
arr[1]();  // ?? 全是4

// 你能把其中的错误改正过来吗? :)


要去赶城铁,就写到这儿吧. 

闭包很简单,,只是大家给形容难了....


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值