麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁(yè) > 語(yǔ)言 > JavaScript > 正文

JavaScript基礎(chǔ)篇(6)之函數(shù)表達(dá)式閉包

2024-05-06 16:26:06
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友
這篇文章主要介紹了javascript基礎(chǔ)篇(6)之函數(shù)表達(dá)式閉包的相關(guān)資料,需要的朋友可以參考下
 

 其實(shí)js支持函數(shù)閉包的主要原因是因?yàn)閖s需要函數(shù)能夠保存數(shù)據(jù)。這里的保存數(shù)據(jù)是只函數(shù)在運(yùn)行結(jié)束以后函數(shù)內(nèi)變量的值也會(huì)進(jìn)行保存。至于為什么js需要在函數(shù)內(nèi)可以保存數(shù)據(jù),那就是js是一種函數(shù)式語(yǔ)言。在函數(shù)內(nèi)保存數(shù)據(jù)是函數(shù)式語(yǔ)言的一大特征。

回顧前面介紹過(guò)的三種定義函數(shù)方式

functiosu(numnumreturnunum//函數(shù)聲明語(yǔ)法定義
vasufunction(numnum)returnunum}//函數(shù)表達(dá)式定義
vasuneFunction("num""num""returnunum")//Functio構(gòu)造函數(shù)

在分析閉包之前我們先來(lái)看看,定義和調(diào)用函數(shù)容易犯的錯(cuò)誤。

例1:

sayHi(); //錯(cuò)誤:函數(shù)還不存在var sayHi = function () {  alert("test");};

例2:

if (true) {  function sayHi() {    alert("1");  }} else {  function sayHi() {    alert("2");  }}sayHi();//打印結(jié)果并不是我們想要的

例3:

var fun1 = function fun2() {  alert("test");}fun2();//錯(cuò)誤:函數(shù)還不存在

在例1中,我們不能在使用函數(shù)聲明式語(yǔ)法定義之前調(diào)用函數(shù)。解決方案:

1.如果使用函數(shù)表達(dá)式定義函數(shù)的話,需要在表達(dá)式定義后調(diào)用。

var sayHi = function () {  alert("test");};sayHi()

2.使用函數(shù)聲明式。(這里瀏覽器引擎會(huì) 函數(shù)聲明提升, 在所有代碼執(zhí)行之前先讀取函數(shù)聲明)

sayHi(); function sayHi () {  alert("test");};

在例2中,我們預(yù)期的結(jié)果應(yīng)該是打印1,實(shí)際結(jié)果是打印2。

if (true) {  function sayHi() {   alert("1");  }  } else {  function sayHi() {   alert("2");  }}sayHi();//打印結(jié)果并不是我們想要的

為什么會(huì)這樣?正因?yàn)?函數(shù)聲明提升 ,所以瀏覽器在預(yù)解析的時(shí)候不會(huì)判斷if條件,直接解析第二個(gè)函數(shù)定義的時(shí)候覆蓋了第一個(gè)。

解決方案:

var sayHi;if (true) {  sayHi = function () {   alert("1");  }  } else {  sayHi = function () {   alert("2");  }}sayHi();

在例3中,發(fā)現(xiàn)只能只用fun1()調(diào)用,而不能使用fun2()調(diào)用。

我自己的理解,真正原因不知道。沒(méi)找到資料。

因?yàn)?: function fun3() { }; 等效與  var fun3 = function fun3() { }; 如圖:

JavaScript基礎(chǔ)篇(6)之函數(shù)表達(dá)式閉包 

所以只能只用fun1()調(diào)用,而不能使用fun2()調(diào)用。

其實(shí)這里我還是有疑問(wèn)的?哪位大神知道,望告知。

既然,fun2在外面不能調(diào)用為什么在函數(shù)內(nèi)部能調(diào)用?雖然在debugger還是得不到fun1。

JavaScript基礎(chǔ)篇(6)之函數(shù)表達(dá)式閉包

好了,通過(guò)上面的三道題目熱身。我們繼續(xù)今天的主題“閉包”。

1.什么是閉包?

定義:就是有權(quán)訪問(wèn)另一個(gè)函數(shù)作用域的變量的函數(shù)

我們先從一個(gè)示例函數(shù)開(kāi)始:

例1:

function fun() {  var a = "張三";}fun();//在我們執(zhí)行完后,變量a就被標(biāo)記為銷(xiāo)毀了

例2:

function fun() {  var a = "張三";  return function () {    alert("test");  }}var f = fun();//同樣,在我們執(zhí)行完后,變量a就被標(biāo)記為銷(xiāo)毀了

例3:

function fun() {  var a = "張三";  return function () {    alert(a);  }}var f = fun();//【現(xiàn)在情況發(fā)生變化了,如果a被銷(xiāo)毀,顯然f被調(diào)用的話就不能訪問(wèn)到變量a的值了】f();//【然后變量a的值正常的被訪問(wèn)到了】//這就是閉包,當(dāng)函數(shù)A 返回的函數(shù)B 里面使用到了函數(shù)A的變量,那么函數(shù)B就使用了閉包。示例:function fun() {  var a = "張三";  return function () {   alert(a);  }}var f = fun();//【現(xiàn)在情況發(fā)生變化了,如果a被銷(xiāo)毀,顯然f被調(diào)用的話就不能訪問(wèn)到變量a的值了】f();//【然后變量a的值正常的被訪問(wèn)到了】

顯然,濫用閉包會(huì)增大內(nèi)存的使用。所以非特殊情況盡量不要使用閉包。如果用到了,記得手動(dòng)設(shè)置空引用,內(nèi)存才能被回收 f = null ;

圖解:(不了解作用域鏈的同學(xué)請(qǐng)先看前面的文章 作用域和作用域鏈 )

JavaScript基礎(chǔ)篇(6)之函數(shù)表達(dá)式閉包

2.什么是匿名函數(shù)? (僅僅只是解釋這個(gè)概念)

如:(即,沒(méi)有名字的函數(shù))

JavaScript基礎(chǔ)篇(6)之函數(shù)表達(dá)式閉包

關(guān)于對(duì)象中函數(shù)的返回值是匿名函數(shù)時(shí),this的怪異現(xiàn)象

講解之前,先清醒下頭腦,不要越看越迷糊了。如果迷糊了,那就直接忽略下面的。

var name1 = "張三";var obj = {  name1: "李四",        fun2: function () {    alert(this.name1);  },  fun3: function () {    return function () {      alert(this.name1);    }  }}

obj.fun2();//打印結(jié)果"李四"意料之中的。
obj.fun3()();//因?yàn)檫@里返回的是一個(gè)函數(shù),所以要再加一對(duì)()來(lái)調(diào)用。打印結(jié)果是"張三",意料之外。
//真是百事不得其解啊,什么this指向了全局?
我們前面講過(guò)“ 哪個(gè)對(duì)象點(diǎn)出來(lái)的方法,this就是哪個(gè)對(duì)象 ”,那我們的  obj.fun3()() 打印的是“張三”也就是說(shuō)this執(zhí)行了全局作用域。

我們看看下面的示例也許就知道為什么了。

var name1 = "張三";var obj = {  name1: "李四",        fun2: function () {    alert(this.name1);  },  fun3: function () {    return function () {      alert(this.name1);    }  }}    //obj.fun3()();var obj2 = {};obj2.name1 = "test";obj2.fun = obj.fun3();obj2.fun();//打印結(jié)果"test",再次證明了“哪個(gè)對(duì)象點(diǎn)出來(lái)的方法,this就是哪個(gè)對(duì)象”.var name1 = "張三";var obj = {  name1: "李四",  fun2: function () {   alert(this.name1);  },  fun3: function () {    return function () {     alert(this.name1);    }  }}//obj.fun3()();var obj2 = {};obj2.name1 = "test";obj2.fun = obj.fun3();obj2.fun();//打印結(jié)果"test",再次證明了“哪個(gè)對(duì)象點(diǎn)出來(lái)的方法,this就是哪個(gè)對(duì)象”.

我們來(lái)分解下 obj.fun3()() 先是  obj.fun3() 返回一個(gè)匿名函數(shù)到了window作用域,然后接著調(diào)用this就指向了window了。( 感覺(jué)解釋有點(diǎn)勉強(qiáng),也不知道對(duì)不,暫時(shí)自己先是這么理解的 )

閉包形成的原因:內(nèi)存釋放問(wèn)題

一般,當(dāng)函數(shù)執(zhí)行完畢后,局部活動(dòng)對(duì)象會(huì)被銷(xiāo)毀,內(nèi)存中僅保存全局作用域,但閉包的情況是不一樣的。

閉包的活動(dòng)對(duì)象依然會(huì)保存在內(nèi)存中,于是像上例中,函數(shù)調(diào)用返回后,變量i是屬于活動(dòng)對(duì)象里面的,就是說(shuō)其棧區(qū)還沒(méi)有釋放,但你調(diào)用c()的時(shí)候i變量保存的作用域鏈從b()->a()->全局去尋找作用域var i聲明所在,然后找到了var i=1;然后在閉包內(nèi)++i;結(jié)果,最后輸出的值就是2了;

以上所述是小編給大家分享的JavaScript基礎(chǔ)篇(6)之函數(shù)表達(dá)式閉包,希望大家喜歡。



注:相關(guān)教程知識(shí)閱讀請(qǐng)移步到JavaScript/Ajax教程頻道。
發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表

圖片精選

主站蜘蛛池模板: 99精品热视频 | 欧美日韩成人一区二区 | av国产片| 久久精品国产99国产精品澳门 | 国产午夜小视频 | 色中色综合| 他也色在线视频 | 国产免费永久在线观看 | 久久综合精品视频 | 国产91中文字幕 | 亚洲一区二区中文 | 在线99热 | 黄色午夜剧场 | 一区二区三区日韩精品 | 国产正在播放 | 黄色影院网站 | 小雪奶水翁胀公吸小说最新章节 | 99国产精品国产免费观看 | 欧美视频国产精品 | 日产精品一区二区三区在线观看 | 午夜视频在线观看免费视频 | 一级黄色影院 | 91精品国产91热久久久做人人 | 黄色大片在线免费看 | 红桃一区| 中文字幕一区2区 | 毛片小网站| 亚洲日本高清 | 成码无人av片在线观看网站 | 亚洲欧美不卡视频 | 懂色粉嫩av久婷啪 | 久久国产乱子伦精品 | 免费观看一级欧美大 | 免费啪视频在线观看 | 九九热在线视频观看 | 精品久久中文网址 | 免费一级特黄欧美大片勹久久网 | 久久逼逼 | 蜜桃av鲁一鲁一鲁一鲁 | 九九热精品视频在线 | 欧美亚洲国产一区二区三区 |