成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

JavaScripts閉包

stefanieliang / 1267人閱讀

摘要:這段代碼中另一個(gè)值得注意的地方,就是這一行,首先在前面沒有使用關(guān)鍵字,因此是一個(gè)全局變量,而不是局部變量。

閉包在js里面的存在就好像奧利奧冰淇淋里面的奧利奧,沒了奧利奧,冰淇淋還是冰淇淋,畢竟js 就是一個(gè)你怎么寫都能好好運(yùn)行的好語言??墒侨藢懙拇a總是要高級(jí)484,所以好好理解閉包好么。

閉包的定義

閉包是指有權(quán)訪問另一個(gè)函數(shù)作用域中的變量的函數(shù),創(chuàng)建閉包的最常見的方式就是在一個(gè)函數(shù)內(nèi)創(chuàng)建另一個(gè)函數(shù),通過另一個(gè)函數(shù)訪問這個(gè)函數(shù)的局部變量

閉包的特性

1.函數(shù)嵌套函數(shù)
2.函數(shù)內(nèi)部可以引用外部的參數(shù)和變量
3.參數(shù)和變量不會(huì)被垃圾回收機(jī)制回收

閉包舉例

下面是一個(gè)更有意思的示例 — makeAdder 函數(shù):

function makeAdder(x) {
  return function(y) {
    return x + y;
  };
}
var add5 = makeAdder(5);
var add10 = makeAdder(10);

console.log(add5(2));  // 7
console.log(add10(2)); // 12

在這個(gè)示例中,我們定義了 makeAdder(x) 函數(shù):帶有一個(gè)參數(shù) x 并返回一個(gè)新的函數(shù)。返回的函數(shù)帶有一個(gè)參數(shù) y,并返回 x 和 y 的和。
從本質(zhì)上講,makeAdder 是一個(gè)函數(shù)工廠 — 創(chuàng)建將指定的值和它的參數(shù)求和的函數(shù),在上面的示例中,我們使用函數(shù)工廠創(chuàng)建了兩個(gè)新函數(shù) — 一個(gè)將其參數(shù)和 5 求和,另一個(gè)和 10 求和。
add5 和 add10 都是閉包。它們共享相同的函數(shù)定義,但是保存了不同的環(huán)境。在 add5 的環(huán)境中,x 為 5。而在 add10 中,x 則為 10。

閉包的實(shí)用性

理論就是這些 — 可是閉包確實(shí)有用嗎?閉包允許將函數(shù)與其所操作的某些數(shù)據(jù)(環(huán)境)關(guān)連起來。這顯然類似于面向?qū)ο缶幊?。在面?duì)象編程中,對(duì)象允許我們將某些數(shù)據(jù)(對(duì)象的屬性)與一個(gè)或者多個(gè)方法相關(guān)聯(lián)。
因而,一般說來,可以使用只有一個(gè)方法的對(duì)象的地方,都可以使用閉包。
在 Web 中,可能想這樣做的情形非常普遍。大部分我們所寫的 Web JavaScript 代碼都是事件驅(qū)動(dòng)的 — 定義某種行為,然后將其添加到用戶觸發(fā)的事件之上(比如點(diǎn)擊或者按鍵)。我們的代碼通常添加為回調(diào):響應(yīng)事件而執(zhí)行的函數(shù)。
閉包的最大用處有兩個(gè),一個(gè)是前面提到的可以讀取函數(shù)內(nèi)部的變量,另一個(gè)就是讓這些變量的值始終保持在內(nèi)存中。

function f1() {
   var n = 999;
   nAdd = function(){
        n += 1
   }
   function f2(){
       console.log(n);
   }
   return f2;
}
var result = f1(); 
result();//999
nAdd(); 
result();//1000

在這段代碼中,result實(shí)際上就是閉包f2函數(shù)。它一共運(yùn)行了兩次,第一次的值是999,第二次的值是1000。這證明了,函數(shù)f1中的局部變量n一直保存在內(nèi)存中,并沒有在f1調(diào)用后被自動(dòng)清除。
為什么會(huì)這樣呢?原因就在于f1是f2的父函數(shù),而f2被賦給了一個(gè)全局變量,這導(dǎo)致f2始終在內(nèi)存中,而f2的存在依賴于f1,因此f1也始終在內(nèi)存中,不會(huì)在調(diào)用結(jié)束后,被垃圾回收機(jī)制(garbage collection)回收。
這段代碼中另一個(gè)值得注意的地方,就是"nAdd=function(){n+=1}"這一行,首先在nAdd前面沒有使用var關(guān)鍵字,因此nAdd是一個(gè)全局變量,而不是局部變量。其次,nAdd的值是一個(gè)匿名函數(shù)(anonymous function),而這個(gè)匿名函數(shù)本身也是一個(gè)閉包,所以nAdd相當(dāng)于是一個(gè)setter,可以在函數(shù)外部對(duì)函數(shù)內(nèi)部的局部變量進(jìn)行操作。

閉包性能考量

如果不是因?yàn)槟承┨厥馊蝿?wù)而需要閉包,在沒有必要的情況下,在其它函數(shù)中創(chuàng)建函數(shù)是不明智的,因?yàn)殚]包對(duì)腳本性能具有負(fù)面影響,包括處理速度和內(nèi)存消耗。

例如,在創(chuàng)建新的對(duì)象或者類時(shí),方法通常應(yīng)該關(guān)聯(lián)于對(duì)象的原型,而不是定義到對(duì)象的構(gòu)造器中。原因是這將導(dǎo)致每次構(gòu)造器被調(diào)用,方法都會(huì)被重新賦值一次(也就是說,為每一個(gè)對(duì)象的創(chuàng)建)。
以下雖然不切實(shí)際但卻說明問題的示例:

function MyObject(name, message) {
  this.name = name.toString();
  this.message = message.toString();
}
MyObject.prototype = {
  getName: function() {
    return this.name;
  },
  getMessage: function() {
    return this.message;
  }
};

上面的代碼并未利用到閉包的益處,因此,應(yīng)該修改為如下常規(guī)形式:

function MyObject(name, message) {
  this.name = name.toString();
  this.message = message.toString();
}

MyObject.prototype = {
  getName: function() {
    return this.name;
  },
  getMessage: function() {
    return this.message;
  }
};

參考備注:

阮一峰 學(xué)習(xí)Javascript閉包(Closure)
MDN Web技術(shù)文檔 JavaScript 閉包

附上我的訂閱號(hào),歡迎關(guān)注,一起學(xué)前端

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/79896.html

相關(guān)文章

  • 簡單理解 JavaScript 閉包問題

    摘要:從我年開始接觸前端,知道閉包這個(gè)詞,已經(jīng)過去兩年了。概念閉包,在高級(jí)程序設(shè)計(jì)里面是這樣介紹的閉包是指有權(quán)訪問另一個(gè)作用域中的變量的函數(shù)。這樣形成的閉包雖然可以使外部可以訪問到內(nèi)部的函數(shù),但是導(dǎo)致了原有的作用域鏈不釋放,會(huì)造成內(nèi)存泄漏。 從我16年開始接觸前端,知道閉包這個(gè)詞,已經(jīng)過去兩年了。這兩年里,閉包這個(gè)概念我在很多地方了解過,卻實(shí)在沒有真的理解,久而久之,變成了一塊心病。這不,趁...

    lyning 評(píng)論0 收藏0
  • 使用CommonJS,AMD以及CMD編寫模塊化JavaScripts

    摘要:模塊化編程首先,我想說說模塊化編程這個(gè)概念當(dāng)我不清楚這個(gè)概念的時(shí)候,其實(shí)說什么模塊化編程多好多好都是懵逼的而我一直不覺得有多好,其實(shí)也是因?yàn)槲覐拈_始寫,就一直都在模塊化編程啊我們寫一個(gè)文件然后我們?cè)谖募幸肴缓笳{(diào)用方法哈哈這樣已經(jīng)是模塊化 模塊化編程 首先,我想說說模塊化編程這個(gè)概念當(dāng)我不清楚這個(gè)概念的時(shí)候,其實(shí)說什么模塊化編程多好多好都是懵逼的而我一直不覺得有多好,其實(shí)也是因?yàn)槲覐?..

    nifhlheimr 評(píng)論0 收藏0
  • JavaScripts toLocaleString (Number)

    摘要:有時(shí)候你寫一個(gè)方法,里面一堆循環(huán),循環(huán)里一堆自己看看都覺得死了其實(shí)人家自帶的方法已經(jīng)寫了,你用一下就好了。好了,撩一張圖。 有時(shí)候你寫一個(gè)方法,里面一堆for循環(huán),for循環(huán)里一堆if else自己看看都覺得low死了其實(shí)人家js自帶的方法已經(jīng)寫了,你用一下就好了。 因?yàn)槲覍慹rp的么,然后就會(huì)用到金額,金額的話一般保留兩位小數(shù),然后用千分位顯示,你打算怎么寫,先用小數(shù)點(diǎn)區(qū)分小數(shù)位和整...

    Salamander 評(píng)論0 收藏0
  • 【全棧】使用Node、Express、Angular、MongoDB構(gòu)建一個(gè)實(shí)時(shí)問卷調(diào)查應(yīng)用程序

    摘要:鑒于此目的,我決定快速構(gòu)建一個(gè)用于此目的的問卷調(diào)查應(yīng)用程序。這將啟動(dòng)一個(gè)服務(wù)器并將應(yīng)用程序部署到該服務(wù)器。圖應(yīng)用程序配置基礎(chǔ)前端這個(gè)問卷調(diào)查應(yīng)用程序?qū)ΤR娪脩艚缑婧筒季质褂昧丝蚣堋? 全棧教程。轉(zhuǎn)自 使用 Node.js、Express、AngularJS 和 MongoDB 構(gòu)建一個(gè)實(shí)時(shí)問卷調(diào)查應(yīng)用程序 最近,在向大學(xué)生們介紹 HTML5 的時(shí)候,我想要對(duì)他們進(jìn)行問卷調(diào)查,并向他們顯...

    BigTomato 評(píng)論0 收藏0
  • 參加第二屆前端開發(fā)者年度大會(huì)總結(jié)

    摘要:代表公司去參加今年的第二屆前端開發(fā)者年度大會(huì),散會(huì)的時(shí)候,技術(shù)老大問我,今天感覺怎么樣,有什么收獲,當(dāng)時(shí)就零零碎碎的回答了一些,不算完美趁著還記得點(diǎn)什么,在這里做個(gè)自我回顧總結(jié),謹(jǐn)代表個(gè)人見解,有不當(dāng)之處,或若涉及圖片隱私或者其它問題,煩請(qǐng) 代表公司去參加今年的 第二屆前端開發(fā)者年度大會(huì),散會(huì)的時(shí)候,Team 技術(shù)老大問我,今天感覺怎么樣,有什么收獲,當(dāng)時(shí)就零零碎碎的回答了一些,不算完...

    solocoder 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<