• javascript 闭包


    闭包的理解:

      简单来说,闭包就是在另一个作用域中保存了一份它从上一级函数或作用域取得的变量(键值对),而这些变量(键值对)是不会随着上一级函数的执行完成而被销毁。

      常用的闭包实现方法:

        1.函数闭包   

    (function(){
        //函数闭包
    })()

        2. try catch

    try{
    
    }catch(e){
         //catch闭包
    }

        3.with 对象闭包

    with(obj){
          //对象闭包
    }

    闭包的常用三种实现方法:

      找一个经典例子来演示闭包的实现方法。

    <!doctype html>
    <title>javascript闭包</title>
    <meta charset="utf-8"/>
    <script type="text/javascript">
      window.onload = function(){
        var lists = document.getElementsByTagName('li');
         for(var i = 0,len = lists.length; i < len; i++){
            lists[i].onclick = function(){
                alert('点击的是:' + i);
            }
         }
      }
    </script>
    <ul>
      <li id="list1">测试列表</li>
      <li id="list2">测试列表</li>
      <li id="list3">测试列表</li>
      <li id="list4">测试列表</li>
      <li id="list5">测试列表</li>
    </ul>

    本来是想点依次点击li弹出0 1 2 3 4,可是弹出的却是4 4 4 4 4。

      注:onclick绑定的函数function(){alert('点击的是:'+i)}的作用域为对应的li对象,而函数里面的i的作用域为window,每次循环window.i的值都被重新赋值,因此,循环完后,i已经是4。所以点击哪个都是4。

     解决方法:

      1. 使用函数闭包

    <!doctype html>
    <title>javascript闭包</title>
    <meta charset="utf-8"/>
    <script type="text/javascript">
      window.onload = function(){
        var lists = document.getElementsByTagName('li');
         for(var i = 0,len = lists.length; i < len; i++){
            lists[i].onclick = (function(){
                var num = i;
                return function(){
                    alert('点击的是:' + num);
                }
            })()
         }
      }
    </script>
    <ul>
      <li id="list1">测试列表</li>
      <li id="list2">测试列表</li>
      <li id="list3">测试列表</li>
      <li id="list4">测试列表</li>
      <li id="list5">测试列表</li>
    </ul>

     或者

    <!doctype html>
    <title>javascript闭包</title>
    <meta charset="utf-8"/>
    <script type="text/javascript">
      window.onload = function(){
        var lists = document.getElementsByTagName('li');
         for(var i = 0,len = lists.length; i < len; i++){
            lists[i].onclick = (function(i){
                return function(){
                    alert('点击的是:' + i);
                }
            })(i)
         }
      }
    </script>
    <ul>
      <li id="list1">测试列表</li>
      <li id="list2">测试列表</li>
      <li id="list3">测试列表</li>
      <li id="list4">测试列表</li>
      <li id="list5">测试列表</li>
    </ul>

      2.使用try...catch语句构造的异常闭包

    <!doctype html>
    <title>javascript闭包</title>
    <meta charset="utf-8"/>
    <script type="text/javascript">
      window.onload = function(){
        var lists = document.getElementsByTagName('li');
        for(var i =0,len = lists.length; i < len; i++){
            try{
                throw i;//自定义抛出异常
            }catch(e){
                lists[e].onclick = function(){
                    alert('点击的是:' + e);
                }
            }
        }
      }
    </script>
    <ul>
      <li id="list1">测试列表</li>
      <li id="list2">测试列表</li>
      <li id="list3">测试列表</li>
      <li id="list4">测试列表</li>
      <li id="list5">测试列表</li>
    </ul>

      3.使用with语句造成的对象闭包

    <!doctype html>
    <title>javascript闭包</title>
    <meta charset="utf-8"/>
    <script type="text/javascript">
      window.onload = function(){
        var lists = document.getElementsByTagName('li');
        for(var i =0,len = lists.length; i < len; i++){
            var obj = {value: i}
            with(obj){
                lists[value].onclick = function(){
                    alert('点击的是:' + value)
                }
            }
        }
      }
    </script>
    <ul>
      <li id="list1">测试列表</li>
      <li id="list2">测试列表</li>
      <li id="list3">测试列表</li>
      <li id="list4">测试列表</li>
      <li id="list5">测试列表</li>
    </ul>

    几个经典有用的实例:

      1.自加

    <!doctype html>
    <title>javascript闭包</title>
    <meta charset="utf-8"/>
    <script type="text/javascript">
        /**
        * 自加
        */
        addSelf = (function(){
            var i = 0;
            return function(){
                return i++;
            }
        })();
        alert(addSelf()) //0
        alert(addSelf()) //1
        alert(addSelf()) //2
    </script>

      2.阶乘

    <!doctype html>
    <title>javascript闭包</title>
    <meta charset="utf-8"/>
    <script type="text/javascript">
        /**
        * 阶乘
        */
        var factorial = function(n){
            if(n < 1){
                alert('invalid arguments');
                return 0;
            }
            if(n == 1){
                return 1;
            }else{
                return n*arguments.callee(n-1);
            }
        }
        alert(factorial(3)) //6
        alert(factorial(4)) //24
    </script>

      3.设置/获取 属性值

    <!doctype html>
    <title>javascript闭包</title>
    <meta charset="utf-8"/>
    <script type="text/javascript">
        function User(properties){
            var self = this;
            for(var i in properties){
                (function(){
                    var property = properties[i];
                    self['get' + i] = function(){
                        return property;
                    }
                    self['set' +i] = function(value){
                        property = value;
                    }
                })();
            }
        }
        //测试代码
        var user = new User({
            name:'Bob',
            age: '27'
        });
        
        alert(user.getname()) //Bob
        alert(user.getage()) // 27
        
        user.setname('Mike');
        alert(user.getname()) //Mike
        alert(user.getage()) // 27
        
        user.setage(22);
        alert(user.getname()) //Mike
        alert(user.getage()) // 22
    </script>
  • 相关阅读:
    网络设备安全需求规格
    web安全法则
    Write Hole 问题
    如何同步master的代码到fork分支代码
    Self assignment
    Uninitialized scalar variable
    Operands of different size in bitwise operation
    Insecure Compiler Optimization
    negative array index read
    Unintended sign extension
  • 原文地址:https://www.cnblogs.com/yangkangkang/p/5643022.html
走看看 - 开发者的网上家园