闭包(一):闭包的9个应用场景

2023-05-28 0 1,058

应用领域1:建立临时性分立回到值

假设想建立两个加总器这种的机能,须要两个临时性表达式用作留存加总状况。放到自上而下回到值或许不太典雅,最简单的方式是建立两个IIFE(立刻继续执行表达式)接着建立表达式,回到两个表达式,接着再表达式中顺利完成加总机能。

// 从前 var n= 0 setInterval(() => console.log(++n), 1000) 拷贝标识符// 那时 setInterval((function() { var n = 0 return function() { console.log(++n) } })(), 1000) 拷贝标识符

应用领域2:化解表达式名武装冲突

借助模块优先选择自上而下表达式的准则,能让表达式外部的小自然环境内管制回到值表达式中文名称。

比如说: jquery会采用自上而下的,但其它库也有可能采用, 但其它库也有可能采用,但其它库也有可能采用那个表达式名,这种就会导致表达式名武装冲突。

假设他们有大批增量标识符采用$那个表达式名初始化jquery,他们不大可能全数重写那个标识符。这时只不过采用即刻表达式就能较好的化解那个难题。

<script src=“https://lib.baomitu.com/jquery/3.6.0/jquery.min.js”></script> <script> // 假设其它库挤占的$ const $ = () => console.log(“Not jQuery”); // 旋量群管制当前回到值的$ (function ($) { $(document).ready(function () { console.log(“Hello jQuery”); }); })(jQuery); $()</script> 拷贝标识符

应用领域3:采用简洁表达式名

第三个情景类似with那个机能

// with主要是用来对对象取值的(复杂结构with影响性能),如下所示:   with(obj) {     var newa = a;     var newb = b;     console.log(newa+newb);   }   该语句 等价于:   var newa = obj.a;   varnewb = obj.b;console.log(newa+newb); 拷贝标识符// 两个复杂的表达式 var data { abc : { efg : 0 } } (function() { console.log(v) })(data.abc.efg) 拷贝标识符

那时有了解构赋值,这两个情景作用不大了。

应用领域4:循环陷阱

作为Javascript面试题八大陷阱题之一,他们下面看看循环陷阱是如何化解的。

循环内加入即刻表达式,由于即刻表达式的模块为实参拷贝关系,相当于拷贝的现场快照

const ary = []; for (var i = 0; i < 5; i++) { (function(n) {· ary.push(function () { return console.log(n); }); })(i) } ary[0](); ary[1](); 拷贝标识符

应用领域5:类库封装

类库封装最重要的要求是不能让类库中的表达式污染自上而下。 比如说jQuery只暴露 $ 就好了

封装1:

(function () { var jQuery = window.$ =function() { // initialize} })() 拷贝标识符jQuery构造器(匿名表达式)赋值给window.$ 作为自上而下表达式为了保证其它标识符改变或删除jQuery表达式 , 所以声明两个局部表达式jQuery, 保证jQuery标识符内都能采用jQuery那个名字。

封装2:

var $ = ( function() { function jQuery() { // Initialize } return jQuery } )() 拷贝标识符

应用领域6:webpack打包模块

A模块 a.js

// a.js const time = Date.now() module.exports = A: + time 拷贝标识符 拷贝标识符

入口index.js

// index.js const a = require(“./a”); console.log(a); 拷贝标识符 拷贝标识符

运行webpack打包

npx webpack 拷贝标识符 拷贝标识符
闭包(一):闭包的9个应用场景
整体采用自运行表达式 – 任何表达式不污染自上而下表达式 o 为模块集合var o = { // 原来的a.js 85: (o) => { const r = Date.now(); o.exports = “A:”+ r; }, }, 拷贝标识符t表达式为exports、require模拟表达式r = {}; // 模拟exports对象 function t(e) { // 模拟require表达式 var n = r[e]; if (void 0 !== n) return n.exports; var s = (r[e] = { exports: {} }); return o[e](s, s.exports, t), s.exports; } 拷贝标识符入口为自继续执行表达式 引用o 、t表达式形成旋量群(() => { const o = t(85); console.log(o); })(); 拷贝标识符 拷贝标识符由于t表达式是表达式提升的所以require表达式也能在子模块里初始化 – 那个大家能自己实验一下。

应用领域7:惰性表达式

惰性表达式表示表达式继续执行的分支只会在表达式第一次初始化的时候继续执行,在第一次初始化过程中,该表达式会被覆盖为另两个按照合适方式继续执行的表达式,这种任何对原表达式的初始化就不用再经过继续执行的分支了。

7.1 实现计算缓存

var square = (function (){ // 注意cache管制大小 var cache = {} return function(n){ return(cache[n] = n * n) } })() 拷贝标识符

7.2 单例模式缓存

实现方式一般是先判断实例是否存在,如果存在就直接回到,否则就建立了再回到。单例模式的好处是避免了重复实例化带来的内存开销。 是避免了重复实例化带来的内存开销。

// 单例模式 function Singleton(){ this.data = singleton; } Singleton.getInstance = (function () { var instance; return function(){ if (instance) { return instance; } else { // 缓存实例 instance = new Singleton(); return instance; } } })(); var sa = Singleton.getInstance(); varsb = Singleton.getInstance();console.log(sa === sb); // true console.log(sa.data); // singleton 拷贝标识符

单例模式前端最典型的应用领域情景,自上而下唯一消息框。

<head> <meta charset=“UTF-8”> <meta name=“viewport” content=“width=device-width, initial-scale=1.0”> <title>Document</title> <style> .model { width: 200px; height: 200px; border: 1px solid aqua; position: fixed; top: 50%; left: 50%; transform: translate(-50%, –50%); text-align: center; } </style> </head><body> <div id=“loginBtn”>点我</div> <script> // 惰性表达式 var getSingle = function (fn) { var result; return function () { //没有缓存 return result || (result = fn.apply(this, arguments)) } } // 建立dom对象 varcreateLoginLayer =function () { var oDiv = document.createElement(“div”); oDiv.innerHTML = “我是登录浮窗”; oDiv.className =“model”; oDiv.style.display = “none”; document.body.appendChild(oDiv); returnoDiv; }var createSingleLoginLayer = getSingle(createLoginLayer); document.getElementById(“loginBtn”).onclick =function () { //动态建立弹窗 //新建两个弹窗实例,外部采用单例模式管理,一直只能有两个. varloginLayer = createSingleLoginLayer(); loginLayer.style.display =“block” } </script> </body> 拷贝标识符

7.3 提高浏览器兼容难题的继续执行效率

bom api兼容

function addEvent(type, element,fun) { if (element.addEventListener) { addEvent = function (type, element, fun) { element.addEventListener(type, fun, false); } } else if(element.attachEvent) { addEvent = function (type, element,fun) { element.attachEvent(on + type, fun); } } else{ addEvent = function (type, element,fun) { element[on + type] = fun; } } return addEvent(type, element, fun); } 拷贝标识符

ajax兼容

function createXHR() { var xhr = null; if (typeof XMLHttpRequest != “undefined”) { xhr = newXMLHttpRequest(); createXHR =function () { return new XMLHttpRequest(); }; } else { try { xhr = newActiveXObject(“Msxml2.XMLHTTP”); createXHR = function () { return new ActiveXObject(“Msxml2.XMLHTTP”); }; }catch (e) { try { xhr = new ActiveXObject(“Microsoft.XMLHTTP”); createXHR = function () { return newActiveXObject(“Microsoft.XMLHTTP”); }; } catch (e) { createXHR = function () { return null; }; } } }return xhr; } 拷贝标识符

应用领域8:表达式颗粒化

应用领域9:hooks

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务