任務(wù)17作業(yè)

問答:

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

  • 函數(shù)聲明必須帶有標(biāo)示符(即函數(shù)名稱)嵌纲,而函數(shù)表達式則可以省略這個標(biāo)示符。
function 函數(shù)名稱 (參數(shù):可選){ 函數(shù)體 } 
  函數(shù)表達式: 
  function 函數(shù)名稱(可選)(參數(shù):可選){ 函數(shù)體 } 
  • 可以看出腥沽,如果不聲明函數(shù)名稱逮走,它肯定是表達式,可如果聲明了函數(shù)名稱的話今阳,如何判斷是函數(shù)聲明還是函數(shù)表達式呢师溅?ECMAScript是通過上下文來區(qū)分的,如果function foo(){}是作為賦值表達式的一部分的話盾舌,那它就是一個函數(shù)表達式墓臭,如果function foo(){}被包含在一個函數(shù)體內(nèi),或者位于程序的最頂部的話矿筝,那它就是一個函數(shù)聲明起便。還有一種函數(shù)表達式不太常見,就是被括號括住的(function foo(){}),他是表達式的原因是因為括號 ()是一個分組操作符榆综,它的內(nèi)部只能包含表達式妙痹。

什么是變量的聲明前置?什么是函數(shù)的聲明前置?

  • JavaScript引擎的工作方式是鼻疮,先解析代碼怯伊,獲取所有被聲明的變量,然后再一行一行地運行判沟,這造成的結(jié)果耿芹,就是所有的變量的聲明語句,都會被提升到代碼的頭部挪哄,這就叫做變量提升吧秕。例如:
var a=1;

而在實際工作的時候JavaScript是這樣讀取代碼的,如下:

  var a;先讀取變量而不讀取其賦值迹炼,也就是說在運行過程中第一時間知曉有這么個定義變量存在砸彬。
  a = 1;  當(dāng)讀取完變量之后才會讀取其賦值。

綜上這就是傳說中的變量聲明前置斯入。

  • 和變量的聲明會前置一樣砂碉,函數(shù)聲明同樣會前置,如果我們使用函數(shù)表達式那么規(guī)則和變量一樣.例如:
console.log(fn); //undefined javascript中運行代碼是一行一行逐一執(zhí)行的刻两,因此在這里就變量中讀取到 (var a;)這里一樣增蹭,console.log中需要執(zhí)行的語句存在但是并沒有定義,因此才會出現(xiàn)undefined磅摹。

var fn = function(){}

如果我們使用函數(shù)聲明的方式滋迈,那么即使函數(shù)寫在最后也可以在前面語句調(diào)用,前提是函數(shù)聲明部分已經(jīng)被下載到本地,例如:

fn(); // "1"
         執(zhí)行函數(shù)fn偏瓤;
function fn(){
    console.log('1');
}

arguments 是什么杀怠?

在JavaScript中椰憋,arguments對象是比較特別的一個對象厅克,實際上是當(dāng)前函數(shù)的一個內(nèi)置屬性。同時arguments對象的長度是由實參個數(shù)而不是形參個數(shù)決定的橙依。形參是函數(shù)內(nèi)部重新開辟內(nèi)存空間存儲的變量证舟,但是其與arguments對象內(nèi)存空間并不重疊。對于arguments和值都存在的情況下窗骑,兩者值是同步的女责,但是針對其中一個無值的情況下,對于此無值的情形值不會得以同步创译。再次利用函數(shù)的arguments屬性可以實現(xiàn)函數(shù)的重載抵知。

函數(shù)的重載怎樣實現(xiàn) ?

  • 在這里首先我們要明確函數(shù)重載的定義:重載是很多面向?qū)ο笳Z言實現(xiàn)多態(tài)的手段之一,在靜態(tài)語言中確定一個函數(shù)的手段是靠方法簽名——函數(shù)名+參數(shù)列表刷喜,也就是說相同名字的函數(shù)參數(shù)個數(shù)不同或者順序不同都被認(rèn)為是不同的函數(shù)残制,稱為函數(shù)重載。
  • 在JavaScript中沒有函數(shù)重載的概念掖疮,函數(shù)通過名字確定唯一性初茶,參數(shù)不同也被認(rèn)為是相同的函數(shù),后面的覆蓋前面的浊闪,這是不是意味著JavaScript不能通過重載功能實現(xiàn)一個函數(shù)恼布,參數(shù)不同功能不同呢?

在JavaScript中搁宾,函數(shù)調(diào)用沒必要把所有參數(shù)都傳入折汞,只要你函數(shù)體內(nèi)做好處理就行,但前提是傳的參數(shù)永遠被當(dāng)做前幾個盖腿,看個例子:

function printPeopleInfo(name, age, sex){
    if(name){
        console.log(name);如前面所說:函數(shù)調(diào)用沒必要把所有參數(shù)都傳入字支,只要你函數(shù)體內(nèi)做好處理就行,這里用條件過濾奸忽,滿足要求則會執(zhí)行相應(yīng)的指令堕伪。
    }

    if(age){
        console.log(age);
    }

    if(sex){
        console.log(sex);
    }
}


printPeopleInfo('Byron', 26);這里兩個參數(shù)在執(zhí)行的時候會對參數(shù)進行判定,到底屬于name age sex中的那一個;滿足其中的兩個栗菜,那么另一個就不會執(zhí)行欠雌。

printPeopleInfo('Byron', 26, 'male');

立即執(zhí)行函數(shù)表達式是什么?有什么作用疙筹?

  • 先創(chuàng)建了一個匿名函數(shù)富俄,然后不傳入?yún)?shù)調(diào)用它,這就變成了立即執(zhí)行函數(shù)而咆。例如:
(function(){})();

其實他的實際結(jié)構(gòu)就是:

(函數(shù)定義表達式)函數(shù)調(diào)用表達式

再看一個例子:

 function fn(){
 console.log(1);
 }  
 這里定義了一個函數(shù)fn霍比,也就是說fn這個函數(shù)就是 前面function fn(){}; 這個整體,那么他的直接調(diào)用就是后邊:(function fn(){
 console.log(1);
 })()暴备;當(dāng)然這里我們沒有加入實參悠瞬。
 fn();調(diào)用此函數(shù)

什么是函數(shù)的作用域鏈?

在大多數(shù)語言中都是用花括號{}來形成一個作用域涯捻,但是在JavaScript中{}并沒有帶來塊作用域浅妆,JavaScript的作用域是靠函數(shù)來形成的,也就是說一個函數(shù)內(nèi)定義的變量函數(shù)外不可以訪問障癌,從而就形成了一個特有的作用區(qū)域凌外,俗稱作用域√握悖看個例子:

function fn(){
  var a =1;

  if(a > 2){
    var b = 3;
  }
  console.log(b);
}

fn(); // undefined

console.log(a); // "ReferenceError: a is not defined  報錯a沒有被定義康辑,個人覺得函數(shù)中并沒有執(zhí)行a,因此在函數(shù)外執(zhí)行console.log(a)就沒法執(zhí)行摄欲,因為獲取不到a的信息,也就是沒有在函數(shù)的作用域中疮薇。

代碼:

1

輸出內(nèi)容為:

function getInfo(name, age, sex){
        console.log('name:',name); 1
        console.log('age:', age);      2
        console.log('sex:', sex);      3
        console.log(arguments);     4
        arguments[0] = 'valley';      5這里重新定義name為valley
        console.log('name', name); 6
    }

    getInfo('hunger', 28, '男');
輸出//name: hunger    1  js中的代碼逐行執(zhí)行蒿涎,因此對應(yīng)上邊的函數(shù)依次解析參數(shù)。
           age: 28           2
           sex: 男            3
    ["hunger", 28, "男"] 4 arguments數(shù)組
      name valley         6
    getInfo('hunger', 28);
輸出://name: hunger    1
             age: 28             2
            sex: undefined   3
              ["hunger", 28]  4 arguments數(shù)組
               name valley    6 

    getInfo('男');
輸出:// name: 男           1
             age: undefined   2  無參數(shù) 所以undefined
             sex: undefined   3
               ["男"]               4
             name valley       6

2惦辛、寫一個函數(shù)劳秋,返回參數(shù)的平方和?如 (難度**)

function sumOfSquares(){ }
 sumOfSquares(2,3,4); // 29
 sumOfSquares(1,3); // 10

答案如下:
  function sumOfSquares(){
     var sum =0; 定義一個變量
     for(var i=0;i<arguments.length;i++){
 sum += arguments[i]*arguments[i]
}利用函數(shù)的arguments屬性實現(xiàn)重載
     console.log(sum); 打印出sum的值                            
}
sumOfSquares(1,3);   輸出10
sumOfSquares(2,3,4); 輸出29

3胖齐、如下代碼的輸出玻淑?為什么 ?

console.log(a);  輸出undefined  變量前置
 var a = 1;
 console.log(b); 報錯找不到b

4呀伙、如下代碼的輸出补履?為什么 ?

sayName('world'); // hello  world
sayAge(10);// 報錯  sayAge不是一個函數(shù)
 function sayName(name){
 console.log('hello ', name); }
 var sayAge = function(age){ // 相當(dāng)于是定義一個變量剿另,因此并不是函數(shù)箫锤,所以不能執(zhí)行。
console.log(age); 
};

5雨女、如下代碼的輸出谚攒?為什么?

function fn(){} //這里fn是一個函數(shù)
var fn = 3; // 此處對fn進行了重新定義氛堕,覆蓋了前者馏臭。
console.log(fn);因此此處應(yīng)該顯示3,但是瀏覽器中執(zhí)行的時候是報錯讼稚。報錯內(nèi)容為:標(biāo)識符的fn已經(jīng)宣布括儒。

6、如下代碼的輸出锐想?為什么帮寻?

function fn(fn2){ console.log(fn2); 
var fn2 = 3; 
console.log(fn2); 
console.log(fn);
 function fn2(){ console.log('fnnn2'); } } 
fn(10);
由于該題中涉及到變量提示和函數(shù)聲明前置,因此該題可以改寫如下:
function fn(fn2){
function fn2(){
            console.log('fnnn2');  
        }
      var fn2赠摇;
       console.log(fn2); 顯示fnnn2
       fn2 = 3;//此處重新定義fn2固逗,因此下邊的執(zhí)行會顯示3
       console.log(fn2); //顯示3
       console.log(fn);  //顯示10
     }
    fn(10);

7、如下代碼的輸出蝉稳?為什么 抒蚜?

var fn = 1; //定義fn為1
 function fn(fn){ console.log(fn); } //這是一個函數(shù)聲明掘鄙,無法自動執(zhí)行
console.log(fn(fn));  //因此在這里會報錯耘戚,報錯原因是由于前邊對變量fn進行了定義,而且權(quán)重高于函數(shù)操漠,如果后邊是console.log(fn)則為1.

8收津、如下代碼的輸出饿这?為什么?

console.log(j);  undefined  
console.log(i);  undefined
 for(var i=0; i<10; i++){ var j = 100; }
 console.log(i); 10 
 console.log(j);  100
作用域存在于函數(shù)中的時候才存在局部作用域撞秋,當(dāng)沒有函數(shù)的時候长捧,除了特殊定義,其余皆可視為全局變量吻贿,因此在該題中 第一行和第二行代碼的執(zhí)行結(jié)果為undefined串结,這也正好體現(xiàn)在js中代碼是逐行執(zhí)行的,當(dāng)執(zhí)行到for循環(huán)的時候舅列,便將i和j視為全局變量肌割,根據(jù)條件對i的限制有0-9共計執(zhí)行10次,因此console.log(i)為10帐要,與此同時變量j被定義為100把敞,因此執(zhí)行console.log(j)為100.

9、如下代碼的輸出榨惠?為什么奋早?

 fn(); // 這里是指執(zhí)行函數(shù)fn,只要函數(shù)存在,執(zhí)行可以在前赠橙。
 var i = 10;
 var fn = 20;
 console.log(i);
 function fn(){
 console.log(i);
 var i = 99;
 fn2();
 console.log(i);
 function fn2(){ i = 100; } }
根據(jù)函數(shù)聲明提前耽装,上題中的代碼可以寫成:
 function fn(){
 console.log(i);
 var i = 99;
 fn2();
 console.log(i);
 function fn2(){ i = 100; }
代碼逐行執(zhí)行,后邊覆蓋前面期揪,因此在這個局部作用域中i的最終值是100剂邮,所以該大函數(shù)fn的執(zhí)行結(jié)果就是100
 }
 fn(); 顯示100
 var i = 10; 全局變量重新定義i
 var fn = 20;
 console.log(i); 因此此處顯示為10

故而輸出結(jié)果為:100 10

10、如下代碼的輸出横侦?為什么挥萌?

var say = 0;
 (function say(n){ 
console.log(n);打印出n
 if(n<3) 條件判斷,當(dāng)n小于3的時候返回結(jié)果枉侧,后邊就不執(zhí)行引瀑。
return; 
say(n-1);執(zhí)行n-1 }( 10 ) );、
因此此處的執(zhí)行結(jié)果為10 9 8 7 6 5 4 3 2 但是為什么沒有1呢榨馁?
因為當(dāng)n=3的時候 依次執(zhí)行console.log(3) 顯示3 同時后邊執(zhí)行say(3-1)憨栽; 顯示2 , 當(dāng)n=2的時候 滿足了后邊的if條件翼虫,就執(zhí)行return,所以沒有1.
 console.log(say); 最后在執(zhí)行這個 因為前面定義了變量say=0屑柔,所以此處顯示0.

首先聲明一點,上題中
(function say(n){ 
console.log(n);
 if(n<3) 
return; 
say(n-1); }( 10 ) );是一個立即執(zhí)行函數(shù)相當(dāng)于()珍剑;只不過括號里邊是一個函數(shù)聲明而已掸宛,但是后邊的10是實參,也就是N的初始值為10.

綜上 執(zhí)行結(jié)果為10 9 8 7 6 5 4 3 2 0

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末招拙,一起剝皮案震驚了整個濱河市唧瘾,隨后出現(xiàn)的幾起案子措译,更是在濱河造成了極大的恐慌,老刑警劉巖饰序,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件领虹,死亡現(xiàn)場離奇詭異,居然都是意外死亡求豫,警方通過查閱死者的電腦和手機塌衰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蝠嘉,“玉大人猾蒂,你說我怎么就攤上這事∈浅浚” “怎么了肚菠?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵徐许,是天一觀的道長捻爷。 經(jīng)常有香客問我边篮,道長厕鹃,這世上最難降的妖魔是什么顾犹? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任逝撬,我火速辦了婚禮系谐,結(jié)果婚禮上虑稼,老公的妹妹穿的比我還像新娘檬寂。我一直安慰自己终抽,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布桶至。 她就那樣靜靜地躺著昼伴,像睡著了一般。 火紅的嫁衣襯著肌膚如雪镣屹。 梳的紋絲不亂的頭發(fā)上圃郊,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天,我揣著相機與錄音女蜈,去河邊找鬼持舆。 笑死,一個胖子當(dāng)著我的面吹牛伪窖,可吹牛的內(nèi)容都是我干的逸寓。 我是一名探鬼主播,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼覆山,長吁一口氣:“原來是場噩夢啊……” “哼竹伸!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起汹买,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤佩伤,失蹤者是張志新(化名)和其女友劉穎聊倔,沒想到半個月后晦毙,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體生巡,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年见妒,在試婚紗的時候發(fā)現(xiàn)自己被綠了孤荣。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡须揣,死狀恐怖盐股,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情耻卡,我是刑警寧澤疯汁,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布,位于F島的核電站卵酪,受9級特大地震影響幌蚊,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜溃卡,卻給世界環(huán)境...
    茶點故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一溢豆、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧瘸羡,春花似錦漩仙、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至峻村,卻和暖如春漱挎,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背雀哨。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工磕谅, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人雾棺。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓膊夹,卻偏偏與公主長得像,于是被迫代替她去往敵國和親捌浩。 傳聞我的和親對象是個殘疾皇子放刨,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,435評論 2 359

推薦閱讀更多精彩內(nèi)容

  • 第5章 引用類型(返回首頁) 本章內(nèi)容 使用對象 創(chuàng)建并操作數(shù)組 理解基本的JavaScript類型 使用基本類型...
    大學(xué)一百閱讀 3,238評論 0 4
  • //Clojure入門教程: Clojure – Functional Programming for the J...
    葡萄喃喃囈語閱讀 3,680評論 0 7
  • 一、函數(shù)聲明和函數(shù)表達式有什么區(qū)別尸饺?(*) ** 1.ECMAScript里面規(guī)定了三種聲明函數(shù)的方式**①構(gòu)造函...
    鴻鵠飛天閱讀 460評論 0 0
  • 前言 人生苦多进统,快來 Kotlin 助币,快速學(xué)習(xí)Kotlin! 什么是Kotlin螟碎? Kotlin 是種靜態(tài)類型編程...
    任半生囂狂閱讀 26,217評論 9 118
  • 望窗外眉菱,近是芭蕉遠是山。遠是山掉分,煙雨朦朧俭缓,不見君來。 香箋無語弄心煩酥郭,鴻雁難去空徘徊华坦。空徘徊不从,小樓殘燭惜姐,相思已亂。
    夤夜的天空閱讀 343評論 0 3