最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

js閉包的6種應(yīng)用場(chǎng)景總結(jié)

 更新時(shí)間:2023年09月19日 08:48:20   作者:xxx17  
如果一個(gè)函數(shù)訪問了此函數(shù)的父級(jí)及父級(jí)以上的作用域變量,那么這個(gè)函數(shù)就是一個(gè)閉包,本文將給大家分享js閉包的6種應(yīng)用場(chǎng)景,文中有詳細(xì)的代碼示例,需要的朋友可以參考下

什么是閉包?

閉包的基本定義

如果一個(gè)函數(shù)訪問了此函數(shù)的父級(jí)及父級(jí)以上的作用域變量,那么這個(gè)函數(shù)就是一個(gè)閉包。閉包會(huì)創(chuàng)建一個(gè)包含外部函數(shù)作用域變量的環(huán)境,并將其保存在內(nèi)存中,這意味著,即使外部函數(shù)已經(jīng)執(zhí)行完畢,閉包仍然可以訪問和使用外部函數(shù)的變量。

//閉包實(shí)例代碼
function fn1() {
  let a = 1;
  function fn2() {
    a++;
    console.log(a);
  }
  return fn2;
}
const fn2 = fn1();
//閉包函數(shù)執(zhí)行完后外部作用域變量仍然存在,并保持狀態(tài)
fn2() //2
fn2() //3

閉包的優(yōu)缺點(diǎn)及特性

  • 閉包的優(yōu)點(diǎn)
  • 保護(hù)變量:閉包可以將變量封裝在函數(shù)內(nèi)部,避免全局污染,保護(hù)變量不被外部訪問和修改。
  • 延長(zhǎng)變量生命周期:閉包使得函數(shù)內(nèi)部的變量在函數(shù)執(zhí)行完后仍然存在,可以在函數(shù)外部繼續(xù)使用。
  • 實(shí)現(xiàn)模塊化:閉包可以創(chuàng)建私有變量和私有方法,實(shí)現(xiàn)模塊化的封裝和隱藏,提高代碼的可維護(hù)性和安全性。
  • 保持狀態(tài):閉包可以捕獲外部函數(shù)的變量,并在函數(shù)執(zhí)行時(shí)保持其狀態(tài)。這使得閉包在事件處理、回調(diào)函數(shù)等場(chǎng)景中非常有用。
  • 閉包的缺點(diǎn)
  • 內(nèi)存占用:閉包會(huì)導(dǎo)致外部函數(shù)的變量無法被垃圾回收,從而增加內(nèi)存占用。如果濫用閉包,會(huì)導(dǎo)致內(nèi)存泄漏問題。
  • 性能損耗:閉包涉及到作用域鏈的查找過程,會(huì)帶來一定的性能損耗。在性能要求高的場(chǎng)景下,需要注意閉包的使用。
  • 閉包的特性
  • 函數(shù)嵌套:閉包的實(shí)現(xiàn)依賴于函數(shù)嵌套,即在一個(gè)函數(shù)內(nèi)部定義另一個(gè)函數(shù)。
  • 記憶外部變量:閉包可以記住并訪問外部函數(shù)的變量,即使外部函數(shù)已經(jīng)執(zhí)行完畢。
  • 延長(zhǎng)作用域鏈:閉包將外部函數(shù)的作用域鏈延長(zhǎng)到內(nèi)部函數(shù)中,使得內(nèi)部函數(shù)可以訪問外部函數(shù)的變量。
  • 返回函數(shù):閉包通常以函數(shù)的形式返回,使得外部函數(shù)的變量仍然可以被內(nèi)部函數(shù)引用和使用。

閉包的應(yīng)用場(chǎng)景

自執(zhí)行函數(shù)

let say = (function(){
  let val = 'hello world';
  function say(){
    console.log(val);
  }
  return say;
})()

節(jié)流防抖

// 節(jié)流函數(shù)封裝
function throttle(func, delay) {
  let timer = null;
  return function () {
    if (!timer) {
      timer = setTimeout(() => {
        func.apply(this, arguments);
        timer = null;
      }, delay);
    }
  };
}
// 防抖函數(shù)封裝
function debounce(func, delay) {
  let timer = null;
  return function () {
    clearTimeout(timer);
    timer = setTimeout(() => {
      func.apply(this, arguments);
    }, delay);
  };
}

函數(shù)柯里化

  • 函數(shù)柯里化(Currying)是一種將多個(gè)參數(shù)的函數(shù)轉(zhuǎn)換為一系列接受單個(gè)參數(shù)的函數(shù)的過程。舉個(gè)簡(jiǎn)單的例子,我們有一個(gè)原始函數(shù)add(a, b, c),我們可以將它柯里化為addCurried(a)(b)(c)的形式。
//柯里化前
function add(a, b, c) {
  return a + b + c;
}
console.log(add(1, 2, 3)); //6
//柯里化后
function addCurried1(a) {
  return function (b) {
    return function (c) {
      return a + b + c;
    };
  };
}
//箭頭函數(shù)簡(jiǎn)寫
const addCurried2 = (a) => (b) => (c) => a + b + c;
console.log(addCurried1(1)(2)(3)); //6
console.log(addCurried2(1)(2)(3)); //6

鏈?zhǔn)秸{(diào)用

  • 利用閉包原理封裝一個(gè)簡(jiǎn)單的計(jì)算器
function calculator() {
  let result = 0;
  function add(num) {
    result += num;
    return this;
  }
  function subtract(num) {
    result -= num;
    return this;
  }
  function multiply(num) {
    result *= num;
    return this;
  }
  function divide(num) {
    result /= num;
    return this;
  }
  function getResult() {
    return result;
  }
  function clear() {
    result = 0;
    return this;
  }
  return {
    add,
    subtract,
    multiply,
    divide,
    getResult,
    clear,
  };
}
const calc = calculator();
const result = calc.add(5).subtract(2).divide(3).multiply(6).getResult();
console.log(result); // 輸出:6

迭代器

function createIterator(arr) {
  let index = 0;
  return {
    next: function() {
      if (index < arr.length) {
        return {
          value: arr[index++],
          done: false
        };
      } else {
        return {
          done: true
        };
      }
    }
  };
}
const myIterator = createIterator([1, 2, 3]);
console.log(myIterator.next()); // { value: 1, done: false }
console.log(myIterator.next()); // { value: 2, done: false }
console.log(myIterator.next()); // { value: 3, done: false }
console.log(myIterator.next()); // { done: true }

發(fā)布-訂閱模式

function createPubSub() {
  // 存儲(chǔ)事件及其對(duì)應(yīng)的訂閱者
  const subscribers = {};
  // 訂閱事件
  function subscribe(event, callback) {
    // 如果事件不存在,則創(chuàng)建一個(gè)新的空數(shù)組
    if (!subscribers[event]) {
      subscribers[event] = [];
    }
    // 將回調(diào)函數(shù)添加到訂閱者數(shù)組中
    subscribers[event].push(callback);
  }
  // 發(fā)布事件
  function publish(event, data) {
    // 如果事件不存在,則直接返回
    if (!subscribers[event]) {
      return;
    }
    // 遍歷訂閱者數(shù)組,調(diào)用每個(gè)訂閱者的回調(diào)函數(shù)
    subscribers[event].forEach((callback) => {
      callback(data);
    });
  }
  // 返回訂閱和發(fā)布函數(shù)
  return {
    subscribe,
    publish,
  };
}
// 使用示例
const pubSub = createPubSub();
// 訂閱事件
pubSub.subscribe("event1", (data) => {
  console.log("訂閱者1收到事件1的數(shù)據(jù):", data);
});
pubSub.subscribe("event2", (data) => {
  console.log("訂閱者2收到事件2的數(shù)據(jù):", data);
});
// 發(fā)布事件
pubSub.publish("event1", "Hello");
// 輸出: 訂閱者1收到事件1的數(shù)據(jù): Hello
pubSub.publish("event2", "World");
// 輸出: 訂閱者2收到事件2的數(shù)據(jù): World

閉包造成的內(nèi)存泄漏怎么解決呢?

閉包中的內(nèi)存泄漏指的是在閉包函數(shù)中,由于對(duì)外部變量的引用而導(dǎo)致這些變量無法被垃圾回收機(jī)制釋放的情況。當(dāng)一個(gè)函數(shù)內(nèi)部定義了一個(gè)閉包,并且這個(gè)閉包引用了外部變量時(shí),如果這個(gè)閉包被其他地方持有,就會(huì)導(dǎo)致外部變量無法被正常釋放,從而造成內(nèi)存泄漏。
解決閉包中的內(nèi)存泄漏問題通常需要注意解除外部變量和閉包函數(shù)的引用,以及解綁函數(shù)本身的引用,使得閉包中引用的外部變量和閉包函數(shù)能夠被垃圾回收機(jī)制釋放。

  • 以下是使用閉包時(shí)解決內(nèi)存泄漏的示例
function createClosure() {
  let value = 'Hello';
  // 閉包函數(shù)
  var closure = function() {
    console.log(value);
  };
  // 解綁定閉包函數(shù),并釋放資源
  var releaseClosure = function() {
    value = null; // 解除外部變量的引用
    closure = null; // 解除閉包函數(shù)的引用
    releaseClosure = null; // 解除解綁函數(shù)的引用
  };
  // 返回閉包函數(shù)和解綁函數(shù)
  return {
    closure,
    releaseClosure
  };
}
// 創(chuàng)建閉包
var closureObj = createClosure();
// 調(diào)用閉包函數(shù)
closureObj.closure(); // 輸出:Hello
// 解綁閉包并釋放資源
closureObj.releaseClosure();
// 嘗試調(diào)用閉包函數(shù),此時(shí)已解綁,不再引用外部變量
closureObj.closure(); // 輸出:null

以上就是js閉包的6種應(yīng)用場(chǎng)景總結(jié)的詳細(xì)內(nèi)容,更多關(guān)于js閉包應(yīng)用場(chǎng)景的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • JsDom 編程小結(jié)

    JsDom 編程小結(jié)

    JsDom編程小結(jié),需要進(jìn)行dom操作的朋友可以參考下。
    2011-08-08
  • JS實(shí)現(xiàn)的四級(jí)密碼強(qiáng)度檢測(cè)功能示例

    JS實(shí)現(xiàn)的四級(jí)密碼強(qiáng)度檢測(cè)功能示例

    這篇文章主要介紹了JS實(shí)現(xiàn)的四級(jí)密碼強(qiáng)度檢測(cè)功能,具有實(shí)時(shí)檢測(cè)輸入密碼強(qiáng)度的功能,涉及javascript針對(duì)字符串的正則判定相關(guān)操作技巧,需要的朋友可以參考下
    2017-05-05
  • 微信小程序?qū)崿F(xiàn)左右聯(lián)動(dòng)

    微信小程序?qū)崿F(xiàn)左右聯(lián)動(dòng)

    這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)左右聯(lián)動(dòng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • 微信小程序 button樣式設(shè)置為圖片的方法

    微信小程序 button樣式設(shè)置為圖片的方法

    這篇文章主要介紹了微信小程序 button 的樣式設(shè)置為圖片的方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-06-06
  • SWFObject 2.1以上版本語法介紹

    SWFObject 2.1以上版本語法介紹

    用SWFObject 插入flash,好處多多,代碼簡(jiǎn)潔,不會(huì)出現(xiàn)微軟的“單擊此處以激活控件”的提示(據(jù)可靠消息,這個(gè)是微軟惹的官司,其結(jié)果是害苦了用戶)。
    2010-07-07
  • javascript的offset、client、scroll使用方法詳解

    javascript的offset、client、scroll使用方法詳解

    javascript的offset、client、scroll在使用過程中非常頻繁,接下來將對(duì)此進(jìn)行一一介紹,需要了解的朋友可以詳細(xì)參考下
    2012-12-12
  • bootstrap響應(yīng)式表格實(shí)例詳解

    bootstrap響應(yīng)式表格實(shí)例詳解

    這篇文章主要為大家詳細(xì)介紹了bootstrap響應(yīng)式表格的實(shí)例代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • js實(shí)現(xiàn)數(shù)組轉(zhuǎn)換成json

    js實(shí)現(xiàn)數(shù)組轉(zhuǎn)換成json

    本文給大家分享的是使用javascript實(shí)現(xiàn)的數(shù)組轉(zhuǎn)換json的代碼,非常簡(jiǎn)單實(shí)用,相當(dāng)于JSON.stringify(array);,有需要的小伙伴可以參考下。
    2015-06-06
  • JavaScript+html5 canvas制作的圓中圓效果實(shí)例

    JavaScript+html5 canvas制作的圓中圓效果實(shí)例

    這篇文章主要介紹了JavaScript+html5 canvas制作的圓中圓效果,結(jié)合完整實(shí)例形式分析了基于JavaScript與html5 canvas技術(shù)實(shí)現(xiàn)的圖形繪制與顏色隨機(jī)填充技巧,需要的朋友可以參考下
    2016-01-01
  • JS異步代碼單元測(cè)試之神奇的Promise

    JS異步代碼單元測(cè)試之神奇的Promise

    這篇文章主要介紹了JS異步代碼單元測(cè)試之神奇的Promise,對(duì)異步感興趣的同學(xué),可以參考下
    2021-05-05

最新評(píng)論

隆安县| 丹东市| 洛宁县| 安国市| 乡宁县| 双鸭山市| 会宁县| 溧阳市| 黎平县| 怀化市| 仁化县| 晴隆县| 陵水| 威海市| 甘孜县| 霍山县| 金华市| 乌审旗| 清水县| 黄陵县| 青海省| 邛崃市| 鸡东县| 额尔古纳市| 扎囊县| 仙居县| 裕民县| 东海县| 邯郸县| 确山县| 星子县| 新昌县| 石楼县| 宜章县| 台东县| 长汀县| 陈巴尔虎旗| 依兰县| 始兴县| 威信县| 沿河|