国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

javascript閉包介紹

weij / 1266人閱讀

摘要:下面這個(gè)例子就是閉包,函數(shù)能夠訪問(wèn)到不在其代碼塊里的變量。然而事實(shí)恰恰相反,唯一的解釋就是是一個(gè)閉包。性能問(wèn)題執(zhí)行一次,就會(huì)重新構(gòu)造兩個(gè)函數(shù)。正確的做法應(yīng)該是參考資料深入理解閉包學(xué)習(xí)閉包阮一峰

概念

閉包(closure)是一個(gè)擁有任意變量以及綁定這些變量的環(huán)境(environment)的表達(dá)式(一般來(lái)說(shuō)是就是function)

A "closure" is an expression (typically a function) that can have free variables together with an environment that binds those variables (that "closes" the expression).

在作用域內(nèi)且在function定義時(shí)被訪問(wèn)的變量,那么這個(gè)變量就一直能夠被那個(gè)function訪問(wèn)。

variables that are in scope and accessed from a function declaration will stay accessible by that function.

下面這個(gè)例子就是閉包,displayName函數(shù)能夠訪問(wèn)到不在其代碼塊里的name變量。

function init() {
  var name = "Mozilla";
  function displayName() {
    alert(name);
  }
  displayName();
}
init();
函數(shù)的作用域 functional scoping

一個(gè)變量的作用域是以其所在的源代碼的位置來(lái)定義的,嵌套在里面的function可以訪問(wèn)到聲明在外層作用域的變量

The scope of a variable is defined by its location within the source code, and nested functions have access to variables declared in their outer scope.

還是拿剛才那個(gè)例子來(lái)說(shuō),displayName函數(shù)是嵌套在init函數(shù)里的,所以它能夠訪問(wèn)到init函數(shù)里的變量

function init() {
  var name = "Mozilla";
  function displayName() {
    alert(name);
  }
  displayName();
}
init();
閉包的組成

先看一下這個(gè)例子:

function makeFunc() {
  var name = "Mozilla";
  function displayName() {
    alert(name);
  }
  return displayName;
}

var myFunc = makeFunc();
myFunc();

按照java或C++的經(jīng)驗(yàn),局部變量name的生命周期在函數(shù)的執(zhí)行后就結(jié)束了,所以會(huì)推斷namemakeFunc()訪問(wèn)后應(yīng)該就訪問(wèn)不到了。
然而事實(shí)恰恰相反,唯一的解釋就是myFunc是一個(gè)閉包(closure)。

閉包由兩部分組成:

function

創(chuàng)建該function的環(huán)境(創(chuàng)建閉包時(shí),作用域內(nèi)的所有局部變量)

對(duì)應(yīng)到上面的這個(gè)例子里:

function: displayName

環(huán)境:name="Mozilla"

再看一個(gè)例子:

function makeAdder(x) {
  return function(y) {
    return x + y;
  };
}

var add5 = makeAdder(5);
var add10 = makeAdder(10);

alert(add5(2));  // 7
alert(add10(2)); // 12

這個(gè)例子說(shuō)明閉包的function可以是相同的,但是環(huán)境可以是不同的,因此就會(huì)有不同的結(jié)果。

歸納

因此可以將閉包歸納為:

定義時(shí),確定可訪問(wèn)變量

執(zhí)行時(shí),確定變量的值

常見(jiàn)錯(cuò)誤

下面這段代碼實(shí)際上執(zhí)行的時(shí)候并不是alert 0,1,2,3,4,而是alert 5次5。
這是為什么?因?yàn)閕變量在for循環(huán)后變成了5,而在執(zhí)行的時(shí)候我們才會(huì)確定閉包里i的值,在定義的時(shí)候不會(huì)記住i的值是什么的。

var funcs = [];
for(var i=0; i < 5; i++) {
  funcs[i] = function() { alert(i); }
}

for(var j=0; j < funcs.length; j++) {
  funcs[j]();
}

正確的寫(xiě)法是:

var funcs = [];
function makeFunc(x) {
  return function() { alert(x); }
}
for(var i=0; i < 5; i++) {
  funcs[i] = makeFunc(i)
}

for(var j=0; j < funcs.length; j++) {
  funcs[j]();
}
閉包實(shí)踐 函數(shù)工廠
function makeSizer(size) {
  return function() {
    document.body.style.fontSize = size + "px";
  };
}

var size12 = makeSizer(12);
var size14 = makeSizer(14);
var size16 = makeSizer(16);
私有變量
var Counter = (function() {
  var privateCounter = 0;
  function changeBy(val) {
    privateCounter += val;
  }
  return {
    increment: function() {
      changeBy(1);
    },
    decrement: function() {
      changeBy(-1);
    },
    value: function() {
      return privateCounter;
    }
  }
})();

alert(Counter.value()); /* Alerts 0 */
Counter.increment();
Counter.increment();
alert(Counter.value()); /* Alerts 2 */
Counter.decrement();
alert(Counter.value()); /* Alerts 1 */

在這個(gè)例子里:

外界不能訪問(wèn): privateCounter,changeBy

外界間接訪問(wèn): increment,decrement,value

私有變量+函數(shù)工廠
var makeCounter = function() {
  var privateCounter = 0;
  function changeBy(val) {
    privateCounter += val;
  }
  return {
    increment: function() {
      changeBy(1);
    },
    decrement: function() {
      changeBy(-1);
    },
    value: function() {
      return privateCounter;
    }
  }  
};

var Counter1 = makeCounter();
var Counter2 = makeCounter();
alert(Counter1.value()); /* Alerts 0 */
Counter1.increment();
Counter1.increment();
alert(Counter1.value()); /* Alerts 2 */
Counter1.decrement();
alert(Counter1.value()); /* Alerts 1 */
alert(Counter2.value()); /* Alerts 0 */

Counter1和Counter2綁定的環(huán)境相互獨(dú)立。

性能問(wèn)題
function MyObject(name, message) {
  this.name = name.toString();
  this.message = message.toString();
  this.getName = function() {
    return this.name;
  };

  this.getMessage = function() {
    return this.message;
  };
}

執(zhí)行一次,就會(huì)重新構(gòu)造兩個(gè)函數(shù)。

正確的做法應(yīng)該是:

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

function MyObject(name, message) {
  this.name = name.toString();
  this.message = message.toString();
}
MyObject.prototype.getName = function() {
  return this.name;
};
MyObject.prototype.getMessage = function() {
  return this.message;
};
參考資料

Closures - MDN

Explaning Javascript Scope and closures

深入理解JavaScript閉包(closure)

學(xué)習(xí)Javascript閉包(Closure) - 阮一峰

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/90878.html

相關(guān)文章

  • 十分鐘快速了解《你不知道的 JavaScript》(上卷)

    摘要:最近剛剛看完了你不知道的上卷,對(duì)有了更進(jìn)一步的了解。你不知道的上卷由兩部分組成,第一部分是作用域和閉包,第二部分是和對(duì)象原型。附錄詞法這一章并沒(méi)有說(shuō)明機(jī)制,只是介紹了中的箭頭函數(shù)引入的行為詞法。第章混合對(duì)象類類理論類的機(jī)制類的繼承混入。 最近剛剛看完了《你不知道的 JavaScript》上卷,對(duì) JavaScript 有了更進(jìn)一步的了解。 《你不知道的 JavaScript》上卷由兩部...

    趙春朋 評(píng)論0 收藏0
  • 【進(jìn)階2-2期】JavaScript深入之從作用域鏈理解閉包

    摘要:使用上一篇文章的例子來(lái)說(shuō)明下自由變量進(jìn)階期深入淺出圖解作用域鏈和閉包訪問(wèn)外部的今天是今天是其中既不是參數(shù),也不是局部變量,所以是自由變量。 (關(guān)注福利,關(guān)注本公眾號(hào)回復(fù)[資料]領(lǐng)取優(yōu)質(zhì)前端視頻,包括Vue、React、Node源碼和實(shí)戰(zhàn)、面試指導(dǎo)) 本周正式開(kāi)始前端進(jìn)階的第二期,本周的主題是作用域閉包,今天是第7天。 本計(jì)劃一共28期,每期重點(diǎn)攻克一個(gè)面試重難點(diǎn),如果你還不了解本進(jìn)階計(jì)...

    simpleapples 評(píng)論0 收藏0
  • javascript的函數(shù)式編程介紹

    摘要:在編程的世界里有兩種基本類型的編程函數(shù)式編程強(qiáng)調(diào)將一系列的動(dòng)作組合成一個(gè)體系對(duì)象式編程強(qiáng)調(diào)將一系列的成分聚合到一個(gè)類中對(duì)于這種弱類語(yǔ)言來(lái)說(shuō),它既有的特點(diǎn)通過(guò)或者封裝一個(gè)類又有的特點(diǎn)。 在編程的世界里有兩種基本類型的編程:函數(shù)式編程(OFP):強(qiáng)調(diào)將一系列的動(dòng)作組合成一個(gè)體系;對(duì)象式編程(OOP):強(qiáng)調(diào)將一系列的成分聚合到一個(gè)類中;對(duì)于javascript這種弱類語(yǔ)言來(lái)說(shuō),它既有OOP的...

    tinna 評(píng)論0 收藏0
  • JavaScript - 收藏集 - 掘金

    摘要:插件開(kāi)發(fā)前端掘金作者原文地址譯者插件是為應(yīng)用添加全局功能的一種強(qiáng)大而且簡(jiǎn)單的方式。提供了與使用掌控異步前端掘金教你使用在行代碼內(nèi)優(yōu)雅的實(shí)現(xiàn)文件分片斷點(diǎn)續(xù)傳。 Vue.js 插件開(kāi)發(fā) - 前端 - 掘金作者:Joshua Bemenderfer原文地址: creating-custom-plugins譯者:jeneser Vue.js插件是為應(yīng)用添加全局功能的一種強(qiáng)大而且簡(jiǎn)單的方式。插....

    izhuhaodev 評(píng)論0 收藏0
  • JavaScript內(nèi)部原理系列-閉包(Closures)

    摘要:對(duì)于采用面向堆棧模型來(lái)存儲(chǔ)局部變量的系統(tǒng)而言,就意味著當(dāng)函數(shù)調(diào)用結(jié)束后,其局部變量都會(huì)從堆棧中移除。因?yàn)樗彩呛瘮?shù)的局部變量,也會(huì)隨著的返回而移除。 概要 本文將介紹一個(gè)在JavaScript經(jīng)常會(huì)拿來(lái)討論的話題 —— 閉包(closure)。閉包其實(shí)已經(jīng)是個(gè)老生常談的話題了; 有大量文章都介紹過(guò)閉包的內(nèi)容(其中不失一些很好的文章,比如,擴(kuò)展閱讀中Richard Cornford的文...

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

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

0條評(píng)論

weij

|高級(jí)講師

TA的文章

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