第十七彈-函數(shù)

問答:

1.函數(shù)聲明和函數(shù)表達(dá)式有什么區(qū)別

函數(shù)聲明 函數(shù)聲明由 function +函數(shù)名+([參數(shù)])+{函數(shù)體} 組成

     console.log(typeof fn);       //這里輸出不是undefined 而是 function 由于 函數(shù)聲明提前的作用
     fn();                                   //函數(shù)調(diào)用
      function fn(){                    //函數(shù)聲明
        console.log("hello")
      }

javaScript引擎將函數(shù)名視同變量名双饥,所以采用 function聲明函數(shù)時,整個函數(shù)(也就是說包括函數(shù)體里面的代碼)會像變量聲明一樣冯键,被提升到代碼頭部。所以上面的代碼不會報錯铝侵。
函數(shù)表達(dá)式

        fn();      //報錯  Uncaught ReferenceError: fn is not defined
  
      var fn=function(){
        console.log("hello")
      }
      fn();    //hello
      }

函數(shù)表達(dá)式只有個執(zhí)行到var fn=function(){}之后才能夠調(diào)用予跌。
所以在如下代碼中榆纽,雖然函數(shù)聲明在函數(shù)表達(dá)式的后面,但是由于函數(shù)聲明被聲明提前了芬探,所以是函數(shù)表達(dá)式相當(dāng)于在函數(shù)的后面神得,函數(shù)表達(dá)式覆蓋了函數(shù)聲明部分。


      var fn=function(){
        console.log("world");
      }
      function fn(){
        console.log("hello");
      }
      fn();   //最后的結(jié)果是world.

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

變量的聲明前置是指變量名的聲明前置

    console.log(fn);   //這里并沒有提示 fn is not defined 而是提示undefined
                               //說明變量fn已經(jīng)聲明過了但是沒有賦值
 var fn=0;            

相當(dāng)于

      var fn;
      console.log(fn);  
      fn=0;     

函數(shù)的生命前置是指整個函數(shù)(包括函數(shù)體)的聲明前置

     console.log(fn);      //輸出 function fn(){console.log("hello")}
      function fn(){
        console.log("hello") 
      }

所以在如下代碼中

     console.log(fn);   //輸出 function fn(){}
     var fn=1;
     function fn(){};
     console.log(fn);   //由于被覆蓋 fn的值變?yōu)?循头;

上面的代碼相當(dāng)于

     var fn;  function fn(){};         
     console.log(fn);   
       fn=1;
     console.log(fn);

3.arguments 是什么

arguments是函數(shù)的參數(shù)集合,在函數(shù)內(nèi)部,你可以使用arguments對象獲取到該函數(shù)的所有傳入?yún)?shù)炎疆。

function fn(){
  console.log(arguments);
}
fn(2,3)   //[2, 3]

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

在java中重載(overloading) 是在一個類里面卡骂,方法名字相同,而參數(shù)不同
參數(shù)不同:包括 對應(yīng)位置的參數(shù)的類型不同形入,參數(shù)的數(shù)量不同全跨。
而作為javascript這種弱類型語言 我們只需要實現(xiàn) 參數(shù)的數(shù)量不同就可以了
我們可以使用arguments來實現(xiàn)方法的重載;

function fn(){
  var sum=0;
  for(var i in arguments){
    sum+=arguments[i];
  }
  return sum;
}
fn(2,3);
fn(1,2,3);

5.立即執(zhí)行函數(shù)表達(dá)式是什么亿遂?有什么作用

立即執(zhí)行表達(dá)式就是在函數(shù)定義后立即執(zhí)行浓若;
而JavaScript引擎規(guī)定,如果function關(guān)鍵字出現(xiàn)在行首蛇数,一律解釋成語句挪钓。所以我們一般用括號括上,變成函數(shù)表達(dá)式+括號 來立即調(diào)用
立即執(zhí)行函數(shù)表達(dá)式= 函數(shù)表達(dá)式+([參數(shù)])耳舅;
常用的寫法

(function fn1(){console.log("hello")})();    
(function fn2(){console.log("world")}());
//其中函數(shù)名可以省略
(function (){console.log("hello")})();   

它的目的有兩個:
一是不必為函數(shù)命名波岛,避免了污染全局變量;
即使是命名了函數(shù)名 也會在執(zhí)行后銷毀
(function fn1(){console.log("hello")})();
console.log(fn1); //報錯 Uncaught ReferenceError: fn1 is not defined

二是IIFE內(nèi)部形成了一個單獨的作用域敦捧,可以封裝一些外部無法讀取的私有變量

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

我們首先要理解什么是作用域
作用域包括 全局作用域和局部作用域

  1. 全局作用域(Global Scope)
    全局作用域有兩種定義方式
  • 定義在最外層的的變量擁有全局作用域
  • 末定義直接賦值的變量自動聲明為擁有全局作用域(這種情況應(yīng)該避免)
function fn(){
   global="hello";
   var inner= "world";
}
fn();
console.log(global);//未定義變量自動聲明為擁有全局作用域  
console.log(inner)  //報錯  inner is not defined

2.局部作用域(Local Scope) 
和全局作用域相反膘魄,局部作用域一般只在固定的代碼片段內(nèi)可訪問到晾蜘,最常見的例如函數(shù)內(nèi)部,
函數(shù)內(nèi)部可以訪問到,在外部不可以。

function fn(){
   var inner= "world";
   console.log(inner);
}
fn();
console.log(inner)  //報錯 inner is not defined

函數(shù)會首先從函數(shù)內(nèi)部開始查找局部變量,然后逐級向上查找呢岗,直到全局變量,這樣便形成了一個關(guān)于作用域的鏈條蛹尝。

var a=1;
function fn1 (){
  var b=10;
  function fn2(){
    console.log(a);
    console.log(b);
  }
  fn2();
}
fn1();
Paste_Image.png

參考文檔:
阮一峰的Blog
夢想天空的Blog
饑人谷的課件

代碼
1.以下代碼輸出什么后豫? (難度**)

function getInfo(name, age, sex){
    console.log('name:',name);
    console.log('age:', age);
    console.log('sex:', sex);
    console.log(arguments);
    arguments[0] = 'valley';
    console.log('name', name);
}

getInfo('hunger', 28, '男');  // name: hunger ,age: 28, sex: "男",  ["hunger",28,"男"] ,name valley
getInfo('hunger', 28);         // name: hunger ,age: 28, sex undefined,  ["hunger",28] ,name valley
getInfo('男');               // name: "男" ,age: undefined, sex undefined,  ["男"] ,name valley

2.寫一個函數(shù),返回參數(shù)的平方和突那?如 (難度**)

function fn(){
  var sum=0;
  if(arguments.length==0) return 0;
  for(var i in arguments){
      var temp=+arguments[i];
      if(temp!==temp) continue;
      sum+= temp*temp;
  }
  return sum;
}

3.如下代碼的輸出挫酿?為什么 (難度*)

 console.log(a);  //undefined   變量聲明提前
 var a = 1; 
console.log(b);  //報錯 b is not defined

4.如下代碼的輸出?為什么 (難度*)

sayName('world');    //hello world
sayAge(10);             //報錯  sayAge is not a function
function sayName(name){
    console.log('hello ', name);
}
var sayAge = function(age){
    console.log(age);
};

5.如下代碼的輸出陨收?為什么 (難度**)

function fn(){}
var fn = 3;
console.log(fn);     //3 由于fn被覆蓋

6.如下代碼的輸出?為什么 (難度***)

function fn(fn2){
   console.log(fn2);        //輸出fn2 函數(shù) 實參被函數(shù)覆蓋掉了
   var fn2 = 3;
   console.log(fn2);          //輸出3  
   console.log(fn);           //輸出fn 函數(shù)
   function fn2(){
        console.log('fnnn2');    
    }
 }
fn(10);

7.如下代碼的輸出鸵赖?為什么 (難度***)

var fn = 1;
function fn(fn){
     console.log(fn);
}
console.log(fn(fn));   //fn是1 不是函數(shù)

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

9.如下代碼的輸出?為什么 (難度****)

fn();
var i = 10;
var fn = 20;
console.log(i);    //10                   fn函數(shù)沒有改變?nèi)肿兞?i的值
function fn(){
    console.log(i);   //undefined      沒有執(zhí)行到 var i=10 i 未定義
    var i = 99;
    fn2();
    console.log(i);   //100             由于fn2 中未定義i  fn2 改變的是 fn中 i的值 
    function fn2(){
        i = 100;
    }
}

10.如下代碼的輸出它褪?為什么 (難度*****)

var say = 0;
(function say(n){
    console.log(n);
    if(n<3) return;      //遞歸調(diào)用  直到n=2 后結(jié)束 10饵骨,9,8茫打,7居触,6,5老赤,4轮洋,3,2抬旺, 
    say(n-1);
}( 10 ));  
console.log(say);    //立即執(zhí)行函數(shù)執(zhí)行完后銷毀 弊予,不會影響say   0
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市开财,隨后出現(xiàn)的幾起案子汉柒,更是在濱河造成了極大的恐慌,老刑警劉巖责鳍,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件碾褂,死亡現(xiàn)場離奇詭異,居然都是意外死亡历葛,警方通過查閱死者的電腦和手機正塌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人传货,你說我怎么就攤上這事屎鳍。” “怎么了问裕?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵逮壁,是天一觀的道長。 經(jīng)常有香客問我粮宛,道長窥淆,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任巍杈,我火速辦了婚禮忧饭,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘筷畦。我一直安慰自己词裤,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布鳖宾。 她就那樣靜靜地躺著吼砂,像睡著了一般。 火紅的嫁衣襯著肌膚如雪鼎文。 梳的紋絲不亂的頭發(fā)上渔肩,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天,我揣著相機與錄音拇惋,去河邊找鬼周偎。 笑死,一個胖子當(dāng)著我的面吹牛撑帖,可吹牛的內(nèi)容都是我干的蓉坎。 我是一名探鬼主播,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼胡嘿,長吁一口氣:“原來是場噩夢啊……” “哼袍嬉!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起灶平,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤伺通,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后逢享,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體罐监,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年瞒爬,在試婚紗的時候發(fā)現(xiàn)自己被綠了弓柱。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片沟堡。...
    茶點故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖矢空,靈堂內(nèi)的尸體忽然破棺而出航罗,到底是詐尸還是另有隱情,我是刑警寧澤屁药,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布粥血,位于F島的核電站,受9級特大地震影響酿箭,放射性物質(zhì)發(fā)生泄漏复亏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一缭嫡、第九天 我趴在偏房一處隱蔽的房頂上張望缔御。 院中可真熱鬧,春花似錦妇蛀、人聲如沸耕突。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽眷茁。三九已至,卻和暖如春古程,著一層夾襖步出監(jiān)牢的瞬間蔼卡,已是汗流浹背喊崖。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工挣磨, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人荤懂。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓茁裙,卻偏偏與公主長得像,于是被迫代替她去往敵國和親节仿。 傳聞我的和親對象是個殘疾皇子晤锥,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,779評論 2 354

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