亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

JavaScript基礎篇(6)之函數表達式閉包

2019-11-20 11:02:07
字體:
來源:轉載
供稿:網友

 其實js支持函數閉包的主要原因是因為js需要函數能夠保存數據。這里的保存數據是只函數在運行結束以后函數內變量的值也會進行保存。至于為什么js需要在函數內可以保存數據,那就是js是一種函數式語言。在函數內保存數據是函數式語言的一大特征。

回顧前面介紹過的三種定義函數方式

functiosu(numnumreturnunum//函數聲明語法定義
vasufunction(numnum)returnunum}//函數表達式定義
vasuneFunction("num""num""returnunum")//Functio構造函數

在分析閉包之前我們先來看看,定義和調用函數容易犯的錯誤。

例1:

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

例2:

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

例3:

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

在例1中,我們不能在使用函數聲明式語法定義之前調用函數。解決方案:

1.如果使用函數表達式定義函數的話,需要在表達式定義后調用。

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

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

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

在例2中,我們預期的結果應該是打印1,實際結果是打印2。

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

為什么會這樣?正因為 函數聲明提升 ,所以瀏覽器在預解析的時候不會判斷if條件,直接解析第二個函數定義的時候覆蓋了第一個。

解決方案:

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

在例3中,發現只能只用fun1()調用,而不能使用fun2()調用。

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

因為1: function fun3() { }; 等效與  var fun3 = function fun3() { }; 如圖:

 

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

其實這里我還是有疑問的?哪位大神知道,望告知。

既然,fun2在外面不能調用為什么在函數內部能調用?雖然在debugger還是得不到fun1。

 

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

1.什么是閉包?

定義:就是有權訪問另一個函數作用域的變量的函數

我們先從一個示例函數開始:

例1:

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

例2:

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

例3:

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

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

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

 

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

如:(即,沒有名字的函數)

 

關于對象中函數的返回值是匿名函數時,this的怪異現象

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

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

obj.fun2();//打印結果"李四"意料之中的。
obj.fun3()();//因為這里返回的是一個函數,所以要再加一對()來調用。打印結果是"張三",意料之外。
//真是百事不得其解啊,什么this指向了全局?
我們前面講過“ 哪個對象點出來的方法,this就是哪個對象 ”,那我們的  obj.fun3()() 打印的是“張三”也就是說this執行了全局作用域。

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

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();//打印結果"test",再次證明了“哪個對象點出來的方法,this就是哪個對象”.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();//打印結果"test",再次證明了“哪個對象點出來的方法,this就是哪個對象”.

我們來分解下 obj.fun3()() 先是  obj.fun3() 返回一個匿名函數到了window作用域,然后接著調用this就指向了window了。( 感覺解釋有點勉強,也不知道對不,暫時自己先是這么理解的 )

閉包形成的原因:內存釋放問題

一般,當函數執行完畢后,局部活動對象會被銷毀,內存中僅保存全局作用域,但閉包的情況是不一樣的。

閉包的活動對象依然會保存在內存中,于是像上例中,函數調用返回后,變量i是屬于活動對象里面的,就是說其棧區還沒有釋放,但你調用c()的時候i變量保存的作用域鏈從b()->a()->全局去尋找作用域var i聲明所在,然后找到了var i=1;然后在閉包內++i;結果,最后輸出的值就是2了;

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

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
成人黄在线观看| 菠萝蜜影院一区二区免费| 欧美亚洲国产成人精品| 欧美国产日韩精品| 久久影院模特热| 这里只有视频精品| 日韩在线观看视频免费| 国产在线日韩在线| 国产成人亚洲综合| 日韩在线精品视频| 国产精品狼人色视频一区| 精品丝袜一区二区三区| 日韩有码视频在线| 色偷偷av一区二区三区| 欧美第一黄色网| 久久精品国产精品亚洲| 国产精品香蕉在线观看| 日韩电影大片中文字幕| 亚洲天堂免费观看| 91极品女神在线| 91啪国产在线| 欧美日韩亚洲精品一区二区三区| 国产欧美最新羞羞视频在线观看| 欧美肥老妇视频| 欧美高清自拍一区| 欧美日韩国产中字| 日韩亚洲欧美成人| 欧美一区二三区| 国产精品自拍偷拍| 亚洲变态欧美另类捆绑| 欧美激情精品在线| 欧美精品videossex性护士| www.亚洲人.com| 国产精品扒开腿做爽爽爽视频| 欧美精品第一页在线播放| 国产精品久久久久久一区二区| 国产一区二区黄| 亚洲影视九九影院在线观看| 国产999精品| 成人在线小视频| 国产区亚洲区欧美区| 精品久久久久久久久久久| 日韩欧美一区二区三区| 欧美综合在线观看| 欧美在线一级视频| 久久亚洲成人精品| 欧美激情a在线| 国产精品入口免费视| 国产午夜精品视频免费不卡69堂| 亚洲偷熟乱区亚洲香蕉av| 久久69精品久久久久久久电影好| 在线观看国产精品淫| 国产精品吴梦梦| 欧美乱大交xxxxx另类电影| 国产精品美女主播在线观看纯欲| 在线播放国产一区二区三区| 国产精品你懂得| 在线观看国产精品淫| 亚洲激情在线视频| 亚洲偷欧美偷国内偷| 一本色道久久88综合日韩精品| 91视频国产精品| 欧美日韩综合视频| 成人黄色大片在线免费观看| 欧美日本精品在线| 亚洲自拍偷拍福利| 国产精品日韩一区| 国产999在线观看| 久久综合久久88| 久久精品国产亚洲一区二区| 亚洲影影院av| 欧美日韩午夜剧场| 97色在线视频观看| 亚洲丝袜一区在线| 精品亚洲国产成av人片传媒| 日韩av免费观影| 国产精品va在线| 亚洲国产另类 国产精品国产免费| 日韩中文字幕在线看| 国产精品视频一区二区三区四| 国产成人精品av| 久久久成人精品| 日韩欧美在线观看| 91久久在线视频| 成人免费高清完整版在线观看| 尤物yw午夜国产精品视频明星| 国产精品91久久| 欧美激情奇米色| 国产91在线高潮白浆在线观看| 亚洲精品久久久久久久久久久久久| 国产va免费精品高清在线| 国产一区二区精品丝袜| 黄色精品一区二区| 国产成人久久久精品一区| 欧美激情xxxxx| 亚洲iv一区二区三区| 亚洲精品98久久久久久中文字幕| 国产一区二区久久精品| 国产欧美一区二区三区视频| 欧美人与性动交a欧美精品| 亚洲男女性事视频| 91国偷自产一区二区三区的观看方式| 亚洲黄色在线观看| 久久精品视频播放| 久久久久中文字幕| 国产日韩av高清| 日韩女优人人人人射在线视频| 欧美做受高潮电影o| 国产成人在线一区二区| 国产91色在线免费| 国产精品主播视频| 97超视频免费观看| 日韩在线视频中文字幕| 午夜精品一区二区三区在线视| 国产精品网址在线| 日韩av黄色在线观看| 欧美国产一区二区三区| 久久久久久久久久国产精品| 久久久久久久久爱| 亚洲最大的网站| 国产亚洲aⅴaaaaaa毛片| 91在线精品视频| 日韩网站免费观看| 日韩男女性生活视频| 性日韩欧美在线视频| 中文字幕亚洲无线码a| 国产精品吊钟奶在线| 国产精品嫩草影院一区二区| 国产成人精品综合久久久| 国产91在线高潮白浆在线观看| 亚洲人精品午夜在线观看| 国产精品青青在线观看爽香蕉| 中文字幕国产日韩| 国产亚洲欧洲高清| 欧美成人精品在线播放| 神马国产精品影院av| 日本久久精品视频| 日韩电影中文字幕在线观看| 一区二区欧美激情| 一区二区欧美久久| 插插插亚洲综合网| 亚洲免费视频一区二区| 国产精品无av码在线观看| 亚洲午夜未删减在线观看| 91网站在线免费观看| 国产一区二区三区高清在线观看| 日韩亚洲精品视频| 国产中文字幕亚洲| 日韩av最新在线观看| 欧美精品videos另类日本| 欧美日韩在线视频一区| 午夜精品福利在线观看| 欧美日韩在线观看视频小说| 国产成人jvid在线播放| 亚洲xxxx做受欧美| 美女扒开尿口让男人操亚洲视频网站| 欧美在线一区二区视频| 欧美一区二区三区免费视| 亚洲视频一区二区| 国产视频在线一区二区| 久久6免费高清热精品| 最近2019中文字幕大全第二页| 亚洲最大福利网| 欧美性猛交xxxx富婆弯腰|