zoukankan      html  css  js  c++  java
  • 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
    // 你能把其中的错误改正过来吗? :)

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

  • 相关阅读:
    thinkphp验证码功能
    thinkphp表单验证
    thinkphp操作数据库的CRUD
    thinkphp基础知识
    什么是预测区间,置信区间与预测区间二者的异同是什么?
    好消息! 不用再羡慕Python有jupyter 我R也有Notebook了【附演示视频】
    手把手教你在Windows环境下升级R
    Feather包实现数据框快速读写,你值得拥有
    pycharm设置字体大小
    pycharm显示行号
  • 原文地址:https://www.cnblogs.com/liliuguang/p/9841662.html
Copyright © 2011-2022 走看看