美文网首页
JS_闭包其实很简单

JS_闭包其实很简单

作者: learninginto | 来源:发表于2019-12-08 16:33 被阅读0次

    JS_闭包其实很简单

    闭包.jpg

    闭包其实就是一个函数,执行以后,接受里面返回的函数,然后保存到一个全局变量中。

    要理解闭包,首先必须理解Javascript特殊的变量作用域。
    变量的作用域无非就是两种:全局变量和局部变量。

    Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量。

    • 全局变量
    var a = 6;//a是全局变量
    function fun1(){
        console.log(a)
    }
    fun1();
    
    • 局部变量

    注意:如果b = 6; 前面不写var,b就被升级为全局变量了

    var a = 6
    function fun1(){
        var b = 6;
    }
    fun1();
    console.log(b);//b is not defined
    
    • 如何读取局部变量的值?

    出于种种原因,我们有时候需要得到函数内的局部变量值。
    但是,正常情况下,这是办不到的,只有通过变通方法才能实现。

    function fun1(){
        var a = 6;
        function fun2(){
            return a;
        }
        return fun2;
    }
    console.log(fun1()());
    

    案例中fun1是一个函数,里面套叠了一个fun2的函数,

    因为fun2和a从属一个作用域下,因此可以返回a的值。

    最后执行的把fun2这个函数通过fun1返回出去。

    因此fun1()执行以后就是fun2,而fun2要执行就需要给他再加一个(),因此就变成了fun1()();你也可以通过赋值的方法将它拆解开,例如:

    var fun = fun1();
    var a1 = fun();
    console.log(a1);
    
    • 使用闭包很重要的原因:

    让内部的函数有权访问外部的局部变量,以防止变量的重名污染 。

    var b = 3;
    function fn() {
        var sum = 3;//私有变量,相当于面向对象中的私有private static
        //定义的函数fun1,里面有一个sum,前面我们说过return是可以返回任何值包括函数
        return function () {
            sum++;
            console.log(sum);
        }
    }
    
    var fn1 = fn();
    
    fn1();//4
    fn1();//5
    fn1 = null;
    //直到fn1被赋值为null的时候,fn当中的匿名函数引用才被切断,这时候也把这个sum清理掉了。
    

    由此可见,闭包有如下特点

    • 闭包的特点
    1. 函数嵌套函数
    2. 函数内部可以引用外部的参数和变量
    3. 参数和变量不会被垃圾回收机制回收
    • 闭包的优点
    1. 希望一个变量长期驻扎在内存中
    2. 避免全局变量的污染
    3. 私有成员的存在
    • 利用闭包,返回一个对象或函数

    Utils.js

    var Utils = function(){
        var a = 1;
        return{
            a:2,
            ce:function(){
                a++;
                this.a++;
                console.log(a,this.a);
            }
        }
    }
    var obj = (function(){
        function fun1(){
            
        }
        function fun2(){
            
        }
        return {fn1:fun1, fn2:fun2};
    })
    

    其他页面调用Utils.js

    Utils.ce(); // 打印2,3

    obj.fn1();

    obj.fn2();

    • 利用闭包实现bind()
    Function.prototype.bind1 = function(obj){//这里的函数参数obj,也是局部变量,因此在下面的return语句中,可以访问到
        var self = this;
        return function(){
            return self.apply(obj, Array.from(arguments));
        }
    }
    function fn1(a, b){
        this.a = a;
        this.b = b;
        return this;
    }
    var fn = fn1.bind1({});
    var obj = fn(3, 5);
    console.log(obj);
    
    • 举一反三,应用案例
    Function.prototype.bind1 = function(obj){
        var self = this;
        return function(){
            return self.apply(obj, Array.from(arguments));
        }
    }
    var obj = {
        num:1,
        init:function(){
            document.addEventListener("click"), this.clickHandler.bind1(this);
        },
        clickHandler:function(){
            this.num++;
            console.log(this.num);
        }
    }
    obj.init();
    

    相关文章

      网友评论

          本文标题:JS_闭包其实很简单

          本文链接:https://www.haomeiwen.com/subject/qbvmgctx.html