亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

JavaScript垃圾回收與閉包舉例詳解

 更新時(shí)間:2025年04月03日 08:33:32   作者:weixin_45456477  
閉包和垃圾回收機(jī)制常常作為前端學(xué)習(xí)開發(fā)中的難點(diǎn),也經(jīng)常在面試中遇到這樣的問題,這篇文章主要介紹了JavaScript垃圾回收與閉包的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下

垃圾回收

標(biāo)記清除

當(dāng)變量進(jìn)入環(huán)境時(shí),將其標(biāo)記為“進(jìn)入環(huán)境”。當(dāng)變量離開環(huán)境時(shí),則將其標(biāo)記為“離開環(huán)境”。垃圾回收器會(huì)銷毀那些帶標(biāo)記的值,并回收它們所占用的內(nèi)存空間。

function test() {
  var a = 1; // 函數(shù)調(diào)用時(shí) 被標(biāo)記 進(jìn)入上下文
}
test(); // 函數(shù)執(zhí)行完畢,a的標(biāo)記去掉,被回收

引用計(jì)數(shù)

當(dāng)聲明一個(gè)變量并將一個(gè)引用類型值賦給該變量時(shí),則這個(gè)值的引用次數(shù)就是1。如果同一個(gè)值又被賦給另一個(gè)變量,則該值的引用次數(shù)加1。相反,如果包含對這個(gè)值引用的變量又取得了另外一個(gè)值,則這個(gè)值的引用次數(shù)減1。當(dāng)這個(gè)值的引用次數(shù)變成0時(shí),則說明沒有辦法再訪問這個(gè)值了,因而就可以將其占用的內(nèi)存空間回收回來。當(dāng)垃圾回收器下次再運(yùn)行時(shí),它就會(huì)釋放那些引用次數(shù)為0的值所占用的內(nèi)存。

function test() {
  var a = {}; // a的引用次數(shù)為0,被回收
  var b = a; // a的引用次數(shù)加1,為1
  var c = a; // a的引用次數(shù)再加1,為2
  a = 1; // a的引用次數(shù)減1,為1
  b = 1; // a的引用次數(shù)減1,為0,可以被回收了
  c = 1; // a的引用次數(shù)減1,為0,可以被回收了
}

閉包

閉包是指有權(quán)訪問另一個(gè)函數(shù)作用域中的變量的函數(shù)。創(chuàng)建閉包的常見方式,就是在一個(gè)函數(shù)內(nèi)部創(chuàng)建另一個(gè)函數(shù)。閉包使得函數(shù)可以繼續(xù)訪問定義時(shí)的詞法作用域。

閉包的另一個(gè)用處,是封裝私有變量。

function createCounter() {
  let count = 0;
  return {
    increment: function () {
      count++;
    },
    getCount: function () {
      return count;
    },
  };
}

const counter = createCounter();
counter.increment();
console.log(counter.getCount()); // 1

閉包的缺點(diǎn):

  • 由于閉包會(huì)使得函數(shù)中的變量都被保存在內(nèi)存中,內(nèi)存消耗很大,所以不能濫用閉包,否則會(huì)造成網(wǎng)頁的性能問題,在IE中可能導(dǎo)致內(nèi)存泄露。解決方法是,在退出函數(shù)之前,將不使用的局部變量全部刪除。
  • 閉包會(huì)在父函數(shù)外部,改變父函數(shù)內(nèi)部變量的值。所以,如果你把父函數(shù)當(dāng)作對象(object)使用,把閉包當(dāng)作它的公用方法(Public Method),把內(nèi)部變量當(dāng)作它的私有屬性(private value),這時(shí)一定要小心,不要隨便改變父函數(shù)內(nèi)部變量的值。
  • 閉包的缺點(diǎn)就是常駐內(nèi)存,會(huì)增大內(nèi)存使用量,并且使用不當(dāng)很容易造成內(nèi)存泄露。

閉包的用途

  • 創(chuàng)建私有變量
    function createCounter() {
      let count = 0;
      return {
        increment: function () {
          count++;
        },
        getCount: function () {
          return count;
        },
      };
    }
    
  • 模擬塊級(jí)作用域
    (function () {
      for (var i = 0; i < 10; i++) {
        console.log(i);
      }
    })();
    
  • 實(shí)現(xiàn)柯里化
    function add(a, b, c) {
      return a + b + c;
    }
    
    function curry(fn) {
      return function curried(...args) {
        if (args.length >= fn.length) {
          return fn.apply(this, args);
        } else {
          return function (...args2) {
            return curried.apply(this, args.concat(args2));
          };
        }
      };
    }
    
    const curriedAdd = curry(add);
    console.log(curriedAdd(1)(2)(3)); // 6
    
  • 實(shí)現(xiàn)函數(shù)節(jié)流和防抖
    function throttle(fn, delay) {
      let timer = null;
      return function (...args) {
        if (!timer) {
          timer = setTimeout(() => {
            fn.apply(this, args);
            timer = null;
          }, delay);
        }
      };
    }
    
    function debounce(fn, delay) {
      let timer = null;
      return function (...args) {
        clearTimeout(timer);
        timer = setTimeout(() => {
          fn.apply(this, args);
        }, delay);
      };
    }
    
  • 實(shí)現(xiàn)單例模式
    function Singleton(fn) {
      let instance = null;
      return function (...args) {
        if (!instance) {
          instance = new (fn.bind(this, ...args))();
        }
        return instance;
      };
    }
    
    function User(name) {
      this.name = name;
    }
    
    const createUser = Singleton(User);
    const user1 = createUser('Alice');
    const user2 = createUser('Bob');
    console.log(user1 === user2); // true
    
  • 實(shí)現(xiàn)模塊化開發(fā)
    const module = (function () {
      let privateVar = 0;
      function privateFunc() {
        console.log('privateFunc');
      }
      return {
        publicFunc: function () {
          console.log('publicFunc');
        },
      };
    })();
    module.publicFunc(); // publicFunc
    module.privateFunc(); // TypeError: module.privateFunc is not a function

總結(jié) 

到此這篇關(guān)于JavaScript垃圾回收與閉包的文章就介紹到這了,更多相關(guān)JS垃圾回收與閉包內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論