關于函數

1. 函數聲明和函數表達式有什么區(qū)別?

函數聲明:function fn(){};
函數表達式:var fn=function(){};
區(qū)別: 1. 函數聲明構造的函數要有函數名稱染苛。函數表達式可以是匿名函數。
      2. 函數聲明可以變量提升几缭,所以函數可以在聲明前調用。而函數表達式不可以沃呢。(如圖)
0_1481186355536_QQ截圖20161208163900.jpg

2. 什么是變量的聲明前置年栓?什么是函數的聲明前置?

  • 變量聲明前置:所謂的變量聲明前置就是在一個作用域塊中,所有的變量都被放在塊的開始出聲明(如圖)
0_1481187483634_QQ截圖20161208165622.jpg
  • 函數聲明前置:對于函數聲明薄霜,js解析器會優(yōu)先讀取某抓,確保在所有代碼執(zhí)行之前聲明已經被解析,而函數表達式惰瓜,如同定義其它基本類型的變量一樣否副,只在執(zhí)行到某一句時也會對其進行解析。(如圖)
0_1481188766228_QQ截圖20161208171809.jpg
0_1481188782999_QQ截圖20161208171908.jpg

3. arguments 是什么?

  • arguments不能夠創(chuàng)建崎坊,是函數自身的參數备禀,只有當函數開始執(zhí)行是才能使用
    雖然arguments的使用方法,很像數組奈揍,但是它并不是數組曲尸。
0_1481192600569_QQ截圖20161208182306.jpg
0_1481193644321_QQ截圖20161208184030.jpg

4 .函數的重載怎樣實現

    JS的函數定義可以指定形式參數名稱,多多少少我們會以為js至少可以支持參數個數不同的方法重載男翰,然而遺憾的是這僅僅是一個假象另患,js所有的參數都是以arguments傳遞過去的,這個參數類似于數組奏篙,在函數調用的時候柴淘,所有的實參都是保存在了這個數據結構里面迫淹,我們定義函數的時候所指定的形式參數其實是為這個數據結構里面的數據定義一個快捷的訪問方式。也就是說js所有的函數都是支持無限個參數的为严,加上數據類型是弱類型敛熬,那么JS的函數除了名稱就真的沒有方法區(qū)別了?
  辦法總是有的,我們可以利用JavaScript中的特殊對象arguments來模擬函數重載第股。用它來判斷傳入參數的個數或類型以區(qū)分

0_1481203159145_QQ截圖20161208211906.jpg

5. 立即執(zhí)行函數表達式是什么应民?有什么作用?

  • 執(zhí)行函數表達式是什么
(function(){alert(‘我是匿名函數’)}()); // 用括號把整個表達式包起來
(function(){alert(‘我是匿名函數’)})(); //用括號把函數包起來
  • 作用:
一是不必為函數命名,避免了污染全局變量夕吻;
二是函數內部形成了一個單獨的作用域诲锹,可以封裝一些外部無法讀取的私有變量。

6. 什么是函數的作用域鏈

   作用域就是變量與函數的可訪問范圍涉馅,即作用域控制著變量與函數的可見性和生命周期归园。
在JavaScript中,變量的作用域有全局作用域和局部作用域兩種稚矿。
在代碼中任何地方都能訪問到的對象擁有全局作用域
局部作用域一般只在固定的代碼片段內可訪問到庸诱,最常見的例如函數內部,所有在一些地方也會看到有人把這種作用域稱為函數作用域
   在JavaScript中晤揣,函數也是對象桥爽,實際上,JavaScript里一切都是對象昧识。函數對象和其它對象一樣钠四,擁有可以通過代碼訪問的屬性和一系列僅供JavaScript引擎訪問的內部屬性。其中一個內部屬性是[[Scope]]跪楞,由ECMA-262標準第三版定義缀去,該內部屬性包含了函數被創(chuàng)建的作用域中對象的集合,這個集合被稱為函數的作用域鏈习霹,它決定了哪些數據能被函數訪問朵耕。
  • 舉例:


    0_1481213643993_QQ截圖20161209001349.jpg

1.分析原因:
第一步:首先定義了一個全局變量a,并且將1賦值給這個a淋叶;
第二步:然后建立了一個函數fn()阎曹,在函數fn里面定義了局部變量b,并且賦值2給b煞檩;
第三步:求fn2()的值处嫌,并且定義了fn2()函數,里面是console.log(a)和console.log(c);
第四步:在函數fn中定義了局部變量c并賦值3給c斟湃;
第五步:求函數fn()熏迹;
那么,在這中間發(fā)生了什么呢凝赛?
1.變量提升注暗,全局變量a的聲明提升到最上面變成var = a坛缕;a = 1;
2.函數fn()中的局部變量b和c的變量提升到fn()的最上面變成var b捆昏;var c赚楚;
3.然后函數fn2提升到var b;var c骗卜;的下面宠页,后面接著就是求fn2();
4.變量的賦值在函數fn()的最底下:b = 2寇仓; c = 3举户;
5.求fn()的值,也就是fn2()的值遍烦;
6.執(zhí)行的順序是從上到下的俭嘁,整個函數變成了如下代碼


0_1481214026690_QQ截圖20161209002001.jpg

這個函數中的作用域鏈是這樣的:
1.從上訴可知這個函數的作用域有三個,互成鏈條服猪,分別是(從外到內)①:全局作用域兄淫;②:fn()作用域;③:fn2()作用域
2.執(zhí)行函數fn2()后蔓姚,首先在函數fn2()中console.log(a),fn2()就在自身域中找a慨丐,沒有找到就到上面一層也就是fn()中找a坡脐,也沒有找到,于是就到全局變量中找a房揭,得到a已經被聲明备闲,并且值為1,所以得到a為1捅暴;
3.然后fn2()中console.log(c)恬砂,c在fn2()作用域中也沒有找到,就到上一層fn()作用域中找c蓬痒,而c此時已經被聲明但是并未賦值泻骤,所以console.log(c)會得到undefined;
4.執(zhí)行完函數fn2()得出結果后梧奢,fn2()被銷毀狱掂,得出的值變?yōu)閒n()的值;
上面所訴的就是一個函數的作用域鏈亲轨,總結來說就是趋惨,某個函數尋求變量的時候,在自身作用域中找不到就會到上一層作用域去找惦蚊,一直到全局變量為止器虾,這一個個的作用域連接起來就是作用域鏈讯嫂;

代碼練習

1. 以下代碼輸出什么?

0_1481205029245_QQ截圖20161208215013.jpg
1兆沙、在函數體內部可以通過arguments對象來訪問傳遞給函數的每一個參數欧芽。
2、函數不介意傳遞進來多少個參數挤悉,也不在乎傳進來的參數是什么類型渐裸,如果沒有傳遞值的命名參數將自動被賦予undefined值。
3装悲、arguments的值永遠與對應命名的參數的值保持同步昏鹃。

2. 寫一個函數,返回參數的平方和诀诊?

0_1481207104289_QQ截圖20161208222451.jpg

3 .如下代碼的輸出洞渤?為什么 ?

0_1481207206203_QQ截圖20161208222634.jpg
變量提升:
var a;
console.log(a);
a=1;
console.log(b);
a被聲明但沒有賦值所以第一個undefined;
b沒有被聲明報錯;

4. 如下代碼的輸出属瓣?為什么

0_1481207506909_QQ截圖20161208223136.jpg
sayName函數聲明载迄,跟變量聲明提前一樣,也會進行函數聲明前置抡蛙。所以sayName的函數打印結果為hello world
saAge是函數表達式护昧,不會進行聲明提前,所以當調用表達式在函數表達式前面會報錯提示sayAge is not a function 粗截,如果調試表達式在函數表達式后面惋耙。就能正常使用。

5. 如下代碼的輸出熊昌?為什么

0_1481207732443_QQ截圖20161208223523.jpg
當在同一個作用域內定義了名字相同的變量和方法的話绽榛,無論其順序如何,變量的賦值會覆蓋方法的賦值.

6. 如下代碼的輸出婿屹?為什么

0_1481210060453_QQ截圖20161208231200.jpg
0_1481210150115_QQ截圖20161208231538.jpg

7. 如下代碼的輸出灭美?為什么?

0_1481210407807_QQ截圖20161208231949.jpg
輸出結果是錯誤昂利,fn不是一個函數
原因:fn被聲明并被賦值為1届腐,此時的fn不是一個函數,而console.log(fn(fn))是輸出這個fn這個函數蜂奸,所以發(fā)生沖突梯捕;

8 .如下代碼的輸出?為什么窝撵?
0_1481210792302_QQ截圖20161208232404.jpg

0_1481210929683_QQ截圖20161208232841.jpg

9. 如下代碼的輸出傀顾?為什么

0_1481212564162_QQ截圖20161208234107.jpg
0_1481212586960_QQ截圖20161208235557.jpg

10. 如下代碼的輸出?為什么

0_1481213251035_QQ截圖20161209000147.jpg
0_1481213260572_QQ截圖20161209000415.jpg

版權歸饑人谷--楠柒所有如有轉發(fā)請標明出處謝謝

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末碌奉,一起剝皮案震驚了整個濱河市短曾,隨后出現的幾起案子寒砖,更是在濱河造成了極大的恐慌,老刑警劉巖嫉拐,帶你破解...
    沈念sama閱讀 219,110評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件哩都,死亡現場離奇詭異,居然都是意外死亡婉徘,警方通過查閱死者的電腦和手機漠嵌,發(fā)現死者居然都...
    沈念sama閱讀 93,443評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來盖呼,“玉大人儒鹿,你說我怎么就攤上這事〖肝睿” “怎么了约炎?”我有些...
    開封第一講書人閱讀 165,474評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長蟹瘾。 經常有香客問我圾浅,道長,這世上最難降的妖魔是什么憾朴? 我笑而不...
    開封第一講書人閱讀 58,881評論 1 295
  • 正文 為了忘掉前任狸捕,我火速辦了婚禮,結果婚禮上众雷,老公的妹妹穿的比我還像新娘府寒。我一直安慰自己,他們只是感情好报腔,可當我...
    茶點故事閱讀 67,902評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著剖淀,像睡著了一般纯蛾。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上纵隔,一...
    開封第一講書人閱讀 51,698評論 1 305
  • 那天翻诉,我揣著相機與錄音,去河邊找鬼捌刮。 笑死碰煌,一個胖子當著我的面吹牛,可吹牛的內容都是我干的绅作。 我是一名探鬼主播芦圾,決...
    沈念sama閱讀 40,418評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼俄认!你這毒婦竟也來了个少?” 一聲冷哼從身側響起洪乍,我...
    開封第一講書人閱讀 39,332評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎夜焦,沒想到半個月后壳澳,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 45,796評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡茫经,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,968評論 3 337
  • 正文 我和宋清朗相戀三年巷波,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片卸伞。...
    茶點故事閱讀 40,110評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡抹镊,死狀恐怖,靈堂內的尸體忽然破棺而出瞪慧,到底是詐尸還是另有隱情髓考,我是刑警寧澤,帶...
    沈念sama閱讀 35,792評論 5 346
  • 正文 年R本政府宣布弃酌,位于F島的核電站氨菇,受9級特大地震影響,放射性物質發(fā)生泄漏妓湘。R本人自食惡果不足惜查蓉,卻給世界環(huán)境...
    茶點故事閱讀 41,455評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望榜贴。 院中可真熱鬧豌研,春花似錦、人聲如沸唬党。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,003評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽驶拱。三九已至霜浴,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蓝纲,已是汗流浹背阴孟。 一陣腳步聲響...
    開封第一講書人閱讀 33,130評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留税迷,地道東北人永丝。 一個月前我還...
    沈念sama閱讀 48,348評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像箭养,于是被迫代替她去往敵國和親慕嚷。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,047評論 2 355

推薦閱讀更多精彩內容