• JavaScript闭包、Object对象


    JavaScript闭包

    定义:闭包指一个拥有许多变量和绑定这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。

        function a(){
            var i=0;
            function b(){
                i++;
                alert(i);
            }
            return b;
        }
        var c=a();
        c();//弹出 1
        c();//弹出 2
    

    函数特点:

    1. 函数b嵌套在函数a内部;
    2. 函数a返回函数b。

    当执行var c=a()后,变量c实际上就指向了函数b,再执行c()后就会弹出窗口显示的值。

    当函数a的内部函数b被函数a外的一个变量引用的时候,就创建了一个闭包。

    闭包就是能够读取其他函数内部变量的函数,本质上闭包就是将函数内部和函数外部连接起来的一座桥梁,而非内部能访问外部、外部不能访问内部。

    作用:就是在a执行完后,闭包使得函数a不会释放,因为a的内部函数b的执行需要依赖a的变量。也就使得上述例子中,a中的i一直存在,每次执行c(),i都是自加1后的值。

        //模拟私有变量
        function Counter(start){
            //父函数Counter当做对象使用
            var count=start;
            return{
                sum: function(){
                    count++;
                },
                get: function(){
                    return count;
                }
            }
        }
    
        var fn1=Counter(4);
        fn1.sum();
        console.log(fn1.get());//打印值为 5
    

    在这里,Counter函数返回两个闭包,函数sum和函数get。这两个函数都维持着对外部作用域Counter的引用,因此可以访问作用域内定义的变量count。

    基础应用场景:

    1. 保护函数内的变量安全(以第一个函数为例,函数a中i只有函数b能访问,无法通过其他途径访问到,因此保护了i的安全性);
    2. 在内存中维持一个变量(依然如第一个为例,由于闭包,函数a中i一直存在于内存中,因此每次执行c()都会给i加1)。

    判断下面的代码执行完成的结果可以帮助更好理解闭包:

        var name="The Window";
        var object={
            name: "My Object",
            getNameFunc: function(){
                return function(){
                    return this.name;
                };
            }
        };
        alert(object.getNameFunc()());//弹出 The Window
    
        var name="The Window";
        var object={
            name: "My Object",
            getNameFunc: function(){
                var that=this;
                return function(){
                    return that.name;
                };
            }
        };
        alert(object.getNameFunc()());//弹出 My Object
    

    在for循环中使用闭包

    表示方法()()

    第二个括号里传变量,第一个括号通过一个匿名函数接收第二个括号传递的变量,然后就隐形的定义了一个私有的(局部)变量。

        for(var i=0;i<10;i++){
            (function(w){
                setTimeout(function(){
                    console.log(w);
                },1000)
            })(i);
        }
    
        //这个函数的效果和上面一样
        for(var i=0;i<10;i++){
            setTimeout((function(e){
                return function(){
                    return console.log(e);
                }
            })(i),1000)
        }
    

    在上述例子中,外部的匿名函数会立即执行,并把i作为它的参数,此时函数内w变量就拥有了i的一个拷贝。当传递给setTimeout的匿名函数执行时,它就拥有了对w的引用,而这个值是不会被循环改变的。

    闭包传递的变量接收后不会被释放,一直占用内存(不建议使用)

        <div class="divclosure">
            <button>按钮1</button>
            <butto 大专栏  JavaScript闭包、Object对象n>按钮2</button>
            <button>按钮3</button>
            <button>按钮4</button>
            <button>按钮5</button>
        </div>
        <script>
            var btns=document.querySelectorAll(".divclosure button");
            for(var i=0;i<btns.length;i++){
                btns[i].style.width=80+"px";
                btns[i].style.height=45+"px";
                btns[i].style.borderRadius=10+"px";
                btns[i].style.marginRight=10+"px";
                (function(w){
                    btns[w].onclick=function(){
                        alert(w);
                    }
                })(i);
            }
        </script>
    
        

    Object对象

    1.第一种方法

        <script>
            //object
            var person=new Object();
            //属性
            person.finger=10;
            person.name="人";
            person.age=23;
            //方法
            person.sayHello=function(){
                document.write("你好,我叫"+this.name+";");
            }
            person.sayAge=function(){
                document.write("我今年"+this.age+"岁;");
            }
            person.studyAge=function(study,dream){
                document.write("我"+study+"开始上学的,我希望成为"+dream+";")
            }
            var xiaoming=new Object();
            xiaoming.name="小明";
            xiaoming.age="23";
            person.sayHello();
            person.sayAge();
            person.sayHello.call(xiaoming);
            person.sayAge.call(xiaoming);
            person.studyAge.call(xiaoming,6,"科学家");
            person.studyAge.apply(xiaoming,[6,"科学家"])
        </script>
    
        
    

    call方法:

    改变方法里面的this的指向,方法使用的是原对象的,通过this获得的数据都是call的对象的;也就是调用一个对象的一个方法,以另一个对象替换当前对象。

    function call(obj,[param1[,param2[,…[,paramN]]]])

    obj:这个对象将代替function类里this对象

    params:这个是一个参数列表

    apply方法:

    与call方法意思一样,参数列表不同;也就是调用一个对象的一个方法,以另一个对象替换当前对象。

    function.apply(obj,args)方法能接收两个参数

    obj:这个对象将代替Function类里this对象

    args:这个是数组,它将作为参数传给function(args–>arguments)

  • 相关阅读:
    红黑树的插入操作详解
    Java实现红黑树
    No-sql之redis常用命令
    如何配置JedisPool的参数
    JedisPool使用注意事项
    2-SAT问题的小结
    BZOJ 2142 礼物 组合数学 CRT 中国剩余定理
    BZOJ 4521 CQOI 2016 手机号码 数位DP
    BZOJ 4380 Myjnie 区间DP
    BZOJ 2754 SCOI 2012 喵星球上的点名 后缀数组 树状数组
  • 原文地址:https://www.cnblogs.com/lijianming180/p/12041428.html
Copyright © 2020-2023  润新知