JS_闭包其实很简单

2019-12-08  本文已影响0人  learninginto

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();

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();
上一篇下一篇

猜你喜欢

热点阅读