JavaScript闭包

闭包的实现原理,其实是利用了作用域链的特性,我们都知道作用域链就是在当前执行环境下访问某个变量时,如果不存在就一直向外层寻找,最终寻找到最外层也就是全局作用域,这样就形成了一个链条。 

function test() {
    var arr = [];
    for(var i = 0;i < 10; i ++) {
        arr[i] = function () {
            document.write(i + " ");
        }
    }
    return arr;
}
var myArr = test();
for(var j = 0; j < 10; j++) {
    myArr[j]();
}


输出结果为10 10 10 10 10 10 10 10 10 10
arr[i] = function () {
    document.write(i + " ");
}这个for循环中的语句前面arr[i]是赋值,等号后面的是函数引用,前面与等号后面的函数语句没有关系,只有等到for循环结束时,函数才会执行,而此时执行的是arr[10]
10个函数都与函数test形成闭包,被保存到外部,10个函数共用一个执行器上下文AO,每次i++都会改变AO中的值,所以在索取值的时候是10

function test() {
    var arr = [];
    for(var i = 0;i < 10; i ++) {
        (function (j) {
            arr[j] = function () {
                document.write(j + " ");
            }
        } (i))
    }
    return arr;
}
var myArr = test();
for(var j = 0; j < 10; j++) {
    myArr[j]();
}


输出结果为0 1 2 3 4 5 6 7 8 9
使用立即执行函数,10个立即执行函数都会生成10个值被保存到外部,每个立即执行函数都是挨个对应的
立即执行函数只要读到它就会立即被执行


闭包:函数嵌套,把里面的函数保存到外部,就会形成闭包
 

  function a() {
        function b() {
            var bbb = 234;
            document.write(aaa);
        }
        var aaa = 123;
        return b;
    }
    var glob = 100;
    var demo = a();
    demo();


    输出结果为123;
    这里因为有return b,所以函数b只有被定义,没有执行就被保存到全局

    var demo;
    function test() {
        var abc = 100;
        function a() {
            console.log(abc);
        }
        demo = a;
    }
    test();
    demo();


    这种方法也可以实现内部函数保存到外部形成闭包

用闭包做缓存:

    function test() {
        var food = "apple";
        var obj = {
            eatFood : function () {
                if(food != "") {
                    console.log("I am eating" + food);
                    food = "";
                }else{
                    console.log("There is nothing! empty!")
                }
            },
            pushFood : function (myFood) {
                food = myFood;
            }
        }
        return obj;
    }
    var person = test();
    person.eatFood();
    person.eatFood();
    person.pushFood('banana');
    person.eatFood();


    输出结果为:
        I am eating apple
        There is nothing! empty!
        I am eating banana


eg:

    <ul>
        <li>a</li>
        <li>a</li>
        <li>a</li>
        <li>a</li>
    </ul>


    使用原生js,给每个li元素绑定一个click事件,输出他们的顺序

    function test() {
        var liCollection = document.getElementsByTagName('li');
        for(var i = 0; i < liCollection.length; i++) {
            liCollection[i].onclick = function() {
                console.log(i);
            }
        }
    }
    test();


    点击结果都为4,还是形成闭包的问题
    解决:利用立即执行函数解决

    function test() {
        var liCollection = document.getElementsByTagName('li');
        for(var i = 0; i < liCollection.length; i++) {
            (function (j) {
                liCollection[j].onclick = function() {
                console.log(j);
            }
            }(i))
        }
    }
    test();

    eg:
    写一个方法,求一个字符串的字节长度。(提示:字符串有一个方法charCodeAt();一个中文占两个字节,一个英文占一个字节)
    定义和用法
    charCodeAt()方法可返回指定位置的字符的Unicode编码.这个返回值是0-65535之间的整数。(当返回值是<=255时,为英文,当返回值>255时为中文)
    语法:

    stringObject.charCodeAt(index)

        function retByteslen(target) {
            var count = 0;
            for(var i = 0; i < target.length; i++) {
                if(target.charCodeAt(i) <= 255) {
                    count ++;
                }else if(target.charCodeAt(i) > 255) {
                    count += 2;
                }
            }
            console.log(count);
        }


        运行程序:retByteslen('');
        简化代码:

        function retByteslen(target) {
            var count = target.length;
            for(var i = 0; i < target.length; i++) {
                if(target.charCodeAt(i) > 255) {
                    count ++;
                }
            }
            console.log(count);
        }


,运算符:var a = (2,3),逗号运算符会先计算两边的等式,然后把后边的结果赋值给a
eg:1.写出下面程序的执行结果

        var f = (
            function f() {
                return "1";
            },
            function g() {
                return 2;
            }
        )();
        typeof f;


        输出结果为number,因为有逗号运算符,所以把后边表达式的值赋值给f,所以为number
    
    2.写出下面程序的执行结果:

        var x = 1;
        if(function f() {}) {
            x += typeof f;
        }
        console.log(x);


        输出结果为:1undefined
        if中的function函数被当成表达式后就不是函数定义了,f将消失,所以typeof对于未定义的值为undefined,为字符串类型
 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值