JS中的闭包机制

思惟导图

1、什么是闭包机制

函数执行造成的私有上下文,即能保护里面的私有变量不受外界干扰,也能在当前上下文中保存一些信息(前提:造成的上下文不销毁),上下文中的这种保存和保护机制,就是闭包机制javascript

2、闭包的两大做用

一、保护做用

在这个上下文中会有一些私有的变量AO(XX),这些私有的变量和外界的变量不会冲突(互不影响)java

二、保存做用

某些状况下,上下文中的某些内容被外界占用后,当前上下文并不会出栈销毁,这样就会把上下文中的一些信息储存起来编程

3、闭包的应用

1.利用闭包的保护做用

  • -1).团队协做开发中;
    • A/B共同开发一个页面,最后要把代码合并在一块儿,为了防止全局变量的冲突污染,咱们建议每一个开发者,都把本身的代码放置到一个闭包中(自执行函数执行便可,这样就是私有的上下文)保护起来
// A的代码
(function anonymous() {
    /* 自执行函数执行,会造成一个私有的上下文,在这里声明+定义的变量或者函数都是私有的 */
    var x = 100,
        y = 200;

    function func() {
        // ...
    }
})();

// B的代码
~ function anonymous() {
    // console.log(anonymous); //=>函数自己 
    //=>匿名函数设置的函数名只能在函数里面应用,函数外面是没法访问的
    var x = 200,
        n = 0;

    function func() {
        // ...
    }

    function handled() {
        // ...
    }
}();
// console.log(anonymous); //=>Uncaught ReferenceError: anonymous is not defined 
复制代码
  • -2).封装一个插件或者类库等;
    • 为了防止咱们定义的变量和方法 和 用户定义的冲突,咱们也是须要把全部写的代码放到一个闭包中,例如:jQuery...
/* JQUERY源码一瞥 */

// typeof window !== "undefined" ? window : this 浏览器端window是存在的,因此为window
(function (global, factory) {
 "use strict";
	// => global===window
	// => factory===function (window, noGlobal){...}
	factory(global);
})(window, function (window, noGlobal) {
	// JQUERY的源码
}); 
//=> 利用闭包的机制,把JQ源码看成自执行函数的形参传给函数,完成执行
复制代码

2.利用闭包的保存做用

  • -1).在某些需求中,咱们常常须要造成一个闭包,存储一些值(并且不能销毁),这样来供后面的程序运行使用(例如:惰性函数、柯理化函数、compose函数等JS高阶编程技巧中,就是基于闭包的保存机制实现的)

此时咱们发现一个问题:每一个人的代码都独立了,那咱们每一个人都会用到的公共方法,难道也要都单独写一遍?设计模式

有此需求,必然得有解决办法:浏览器

4、闭包内的值暴露给外面使用的两种方法

需求:咱们须要把某一个闭包(私有上下文)中的值暴露到外面闭包

一、基于window.xxx=xxx暴露到全局

这种办法虽然能够实现,可是也会存在冲突,若是咱们每个版块都须要暴露更多的方法,同时都基于这种方法暴露到全局对象GO上,也可能致使方法之间的冲突函数

(function anonymous() {
    function queryURLParams() {
        // ...
    }

    function sum() {
        // ...
    }

// 想暴露到外面使用,能够暴露到全局上(赋值给全局对象GO =>window)
    window.queryURLParams = queryURLParams;
    window.sum = sum;
})();
queryURLParams(); //=>window.queryURLParams() 
复制代码

二、JS中的设计模式:单例设计模式

每个版块暴露到全局下只有一个变量而已,全部须要供别人调取的方法都在对象中(这样暴露一个或者多个都无所谓)性能

  • 避免了全局变量的污染,也同时实现了不一样闭包之间方法的公用性
var utils = (function anonymous() {
    // queryURLParams:获取URL地址参数信息
    function queryURLParams() {
        // ...
    }

    // sum:实现任意数求和
    function sum() {
        // ...
    }

    // 把须要供外面访问的变量和方法,赋值给一个对象,最后返回(外层基于VAR utils定义变量来接收便可)
    return {
        queryURLParams: queryURLParams,
        sum: sum
    }; //=>return AAAFFF000;
})();
// console.log(utils); //=>{queryURLParams:函数,sum:函数}
utils.queryURLParams();
utils.sum(); 
复制代码

utils对象中包含了须要供别人调取使用的方法;此时咱们把utils称之为“命名空间”,而对象就是一个空间,空间中包含了当前版块中的内容,或者是把当前版块中的内容按照命名空间进行了分组,每个分组都是一个单独的个体 ui

命名空间

  • 把每个对象值 赋值给变量 =>能够理解为,给每个对象的堆内存空间起了个变量名,因此此时能够把这个变量称为 “命名空间”
  • 当前对象中的键值对都是 命名空间 中私有的键值对

5、闭包的优缺点

一、优势

  • 上述咱们一直说的保护和保存做用

二、缺点

  • 由于闭包会产生不销毁的上下文,这样致使栈/堆内存消耗过大,有时候也会致使内存泄漏等,影响页面的运行性能,因此在真实项目中,要合理应用闭包(不要滥用)
相关文章
相关标签/搜索