JS函數(shù)與作用域

如題,本文介紹函數(shù)與作用域的相關(guān)知識(shí)

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

  • 函數(shù)聲明:使用function關(guān)鍵字可以聲明一個(gè)函數(shù)

    例:function foo(){}

  • 函數(shù)表達(dá)式:意即將一個(gè)匿名函數(shù)賦值給一個(gè)變量

    例:var foo=function(){}

  • 區(qū)別:

    (1)函數(shù)聲明必須有標(biāo)識(shí)符悬襟,也就是常說(shuō)的函數(shù)名端仰;函數(shù)表達(dá)式可以省略函數(shù)名

    (2)函數(shù)的聲明不必放到調(diào)用的前面窿侈,函數(shù)調(diào)用的時(shí)候才會(huì)被執(zhí)行。函數(shù)的表達(dá)式則必須放到調(diào)用的前面。

    (3)函數(shù)聲明在JS解析時(shí)進(jìn)行函數(shù)提升,因此在同一個(gè)作用域內(nèi)迎瞧,不管函數(shù)聲明在哪里定義,該函數(shù)都可以進(jìn)行調(diào)用逸吵。而函數(shù)表達(dá)式的值是在JS運(yùn)行時(shí)確定凶硅,并且在表達(dá)式賦值完成后,該函數(shù)才能調(diào)用扫皱。

    在程序執(zhí)行前咏尝,會(huì)先獲取函數(shù)聲明聲明的函數(shù),獲取變量的聲明啸罢,這里變量的聲明只是先開(kāi)辟一個(gè)空間,然后給了個(gè)名字胎食,之后到該變量名賦值的時(shí)候扰才,才有值,也就是說(shuō)厕怜,在未得到該變量的賦值前衩匣,使用該變量會(huì)得到undefined蕾总。

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

  • javascript的變量聲明具有hoisting機(jī)制琅捏,JavaScript引擎在執(zhí)行的時(shí)候生百,會(huì)把所有的聲明都提升到當(dāng)前作用域的最前面

  • 變量聲明前置就是在一個(gè)作用域塊中,所有的變量都被放在塊的開(kāi)始處聲明

    變量的聲明前置柄延,在程序運(yùn)行前蚀浆,先獲取變量的名字,到該變量的賦值語(yǔ)句搜吧,才為該變量賦值市俊,再此前都是undefined

  • 函數(shù)的聲明前置:function 函數(shù)名(){}聲明了一個(gè)函數(shù),在程序運(yùn)行前滤奈,提取所有函數(shù)聲明的函數(shù)摆昧,之后才正式開(kāi)始運(yùn)行函數(shù),所以蜒程,無(wú)論函數(shù)聲明的函數(shù)執(zhí)行語(yǔ)句放在程序的最前面绅你,或者程序的最后面,都能夠正常執(zhí)行

3.arguments 是什么

arguments是函數(shù)內(nèi)部的一個(gè)對(duì)象昭躺,對(duì)應(yīng)著傳進(jìn)來(lái)的參數(shù)忌锯,是一個(gè)類(lèi)數(shù)組對(duì)象,沒(méi)有數(shù)組的操作方法窍仰。

  • 特點(diǎn):

(1)對(duì)象有l(wèi)ength屬性且length的值就是對(duì)象里屬性的數(shù)量

(2)每個(gè)傳進(jìn)來(lái)的參數(shù)對(duì)應(yīng)著arguments[0],arguments[1]汉规,有先后順序之分,通過(guò)下標(biāo)獲取到對(duì)應(yīng)值

比如

function fn(name,age){

console.log(arguments[0];);

console.log(arguments[1];);

}

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

  • 定義:重載函數(shù)就是在同一作用域內(nèi)驹吮,可以有一組具有相同函數(shù)名针史,不同參數(shù)列表的函數(shù),執(zhí)行相應(yīng)的功能

  • 在JS中沒(méi)有函數(shù)重載碟狞。相同的函數(shù)名字啄枕,如果定義的參數(shù)個(gè)數(shù)不一樣,后出現(xiàn)的會(huì)覆蓋先出現(xiàn)的 同名函數(shù)后面的會(huì)覆蓋前面的族沃。

  • 但我們可以通過(guò)在函數(shù)體內(nèi)針對(duì)不同的參數(shù)調(diào)用執(zhí)行相應(yīng)的邏輯频祝,也就類(lèi)似實(shí)現(xiàn)了“重載”的效果。

     例子
      function printPeopleInfo(name, age, sex){
       if(name){
       console.log(name);
      }
    
       if(age){
       console.log(age);
      }
    
      if(sex){
       console.log(sex);
      }
      }
    
      printPeopleInfo('Byron', 26);
      printPeopleInfo('Byron', 26, 'male');
    

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

  • 寫(xiě)法

(1)(function(){ /* code */ }()); // Crockford 推薦這個(gè)

(2)(function(){ /* code */ })(); // 這個(gè)同樣運(yùn)行正常

  • 作用

(1) 函數(shù)會(huì)立即執(zhí)行常空。

(2) 隔離作用域(這個(gè)匿名函數(shù)中的變量與外部環(huán)境的變量隔離,防止了變量的命名沖突盖溺,形成了一個(gè)獨(dú)立的空間漓糙,有助于代碼模塊化。)

6.求n!烘嘱,用遞歸來(lái)實(shí)現(xiàn)

  • 遞歸4個(gè)特點(diǎn):

(1)自己調(diào)用自己

(2)設(shè)定終止條件

(3)優(yōu)點(diǎn):算法簡(jiǎn)單

(4)缺點(diǎn):效率低

  • 例子

    function factor(n){
    if(n===1){
    console.log(n);
    return n;
    }
    var nn=n*factor(n-1)
    console.log(nn)
    return nn
    }  
    factor(5)````
    

    //1*2*3*4*5 結(jié)果:1 2 6 24 120

7.以下代碼輸出什么昆禽?(PS: //注釋就是結(jié)果)

   function getInfo(name, age, sex){
   console.log('name:',name);     //饑人谷-->小谷-->男
   console.log('age:', age);      //2-->3-->undefined
   console.log('sex:', sex);      //男-->undefined-->undefined
   console.log(arguments);        //空(沒(méi)有指定下標(biāo))
   arguments[0] = 'valley';   
   console.log('name', name);     //name valley 
   }
   getInfo('饑人谷', 2, '男');
   getInfo('小谷', 3);
   getInfo('男');

8. 寫(xiě)一個(gè)函數(shù)蝗蛙,返回參數(shù)的平方和?

   <script>
   function sumOfSquares(){
   var result = 0;
   if(arguments.length>0){
   for(var i=0;i<arguments.length;i++){
   result += arguments[i]*arguments[i];
   }
   }
   return result 
   }
   var result =sumOfSquares(2,3,4)
   var result2 =sumOfSquares(1,3)
   console.log(result)
   console.log(result2)
   </script>  

9.如下代碼的輸出醉鳖?為什么

   console.log(a);
   var a = 1;   //undefined
   console.log(b); //報(bào)錯(cuò)
  • 結(jié)果:undefined和報(bào)錯(cuò)
  • 原因:
    (1)變量a的定義var a = 1; 應(yīng)該放到 console.log(a); 的前面捡硅,變量應(yīng)該先定義后輸出。
    (2)b是沒(méi)有被聲明的盗棵,肯定不能直接輸出壮韭。

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

   sayName('world');
   sayAge(10);
   function sayName(name){
       console.log('hello ', name);
   }
   var sayAge = function(age){
    console.log(age);
   }

輸出 :hello,world以及報(bào)錯(cuò)
原因:
function sayName(name){} 是一個(gè)函數(shù)漾根,它可以直接調(diào)用賦值泰涂,聲明和調(diào)用不分先后,沒(méi)有順序
var sayAge = function(age){} 是一個(gè)函數(shù)表達(dá)式辐怕,想要賦值必須先要聲明逼蒙,應(yīng)該放到function(age){}后面

11.如下代碼輸出什么? 寫(xiě)出作用域鏈查找過(guò)程偽代碼

  var x = 10 
  bar() 
  function foo() {
    console.log(x)
  }
  function bar(){
    var x = 30
    foo()
  }

   /*
 1.第一步:執(zhí)行上下文

  globalContext{
    AO:{
     x=10;
     foo:function();
     bar:function();
   },
    Scope:null
  }

  foo.[[scope]]=globalContext.AO
  bar.[[scope]]=globalContext.AO

 2.第二步:調(diào)用bar()

  barContext={
    AO:{
     x:30
     foo:function
    },
    Scope:bar.[[scope]]//globalContext.AO
  }

   bar()  //結(jié)果 x:30

 3.第三步:調(diào)用foo()

  fooContext={
    AO:{}
    Scope:foo.[[scope]]=globalContext.AO
   }
    foo()  //結(jié)果 x:10

    //最終結(jié)果: x:10
   */

12. 如下代碼輸出什么? 寫(xiě)出作用域鏈查找過(guò)程偽代碼

   var x = 10;
   bar() 
   function bar(){
   var x = 30;
   function foo(){
   console.log(x) 
  }
  foo();
  }  


 /*
  第一步:執(zhí)行上下文
  globalContext{
    AO:{
     x:10
     bar:function
    }
    Scope:null
  }
  bar.[[scope]]=globalContext.AO

  第二步:調(diào)用bar()

   barContext={
     AO:{
      x:30
      foo:function
     }
     Scope:bar.[[scope]]=globalContext.AO
   }

  bar()  //結(jié)果 x:30

  第三步:調(diào)用foo()

  fooContext={
    A0:{ }
    Scope:foo.[[scope]]=barContext.AO
  }

  foo() //結(jié)果 x:30

//  bar(){
//  foo()
//  }
//  最終結(jié)果 x:30
*/

13. 以下代碼輸出什么? 寫(xiě)出作用域鏈的查找過(guò)程偽代碼

   var x = 10;
   bar() 
   function bar(){
   var x = 30;
   (function (){
   console.log(x)
   })()
   }


   /*
   第一步:執(zhí)行上下文

   globalContext{
     AO:{
       x:10;
       bar:function
     }
     Scope:null
   }

   bar.[[scope]]=globalContext.AO

   第二步:調(diào)用bar()

   barContext={
     AO:{
       x=30
       :function
     }
     Scope:bar.[[scope]]=globalContext.AO
   }

   第三步:立即執(zhí)行function ()

   functionContext={
     AO:{  }
     Scope:function.[[scope]]//barContext.AO
   }

 //  最終結(jié)果  x:30
*/

14. 以下代碼輸出什么? 寫(xiě)出作用域鏈查找過(guò)程偽代碼

   var a = 1;

   function fn(){
     console.log(a)
     var a = 5
     console.log(a)
     a++
     var a
     fn3()
     fn2()
     console.log(a)

     function fn2(){
       console.log(a)
       a = 20
     }
   }

   function fn3(){
     console.log(a)
     a = 200
   }

   fn()
   console.log(a)


   /*
   //第一步:執(zhí)行上下文
   globalContext:{
     AO:{
       a:1
       fn:function
       fn3:function
     } 
     Scope:null
   }

    fn.[[scope]]=globalContext.A0
    fn3.[[scope]]=globalContext.AO

   //調(diào)用 fn()
   fnContext:{
     AO:{
       a:6
       fn3:function
       fn2:function
     }
    Scope:null
   }
    fn3[[scope]]=fnContext.AO
    fn2[[scope]]=fnContext.AO

   //調(diào)用 fn2()
   fn2Context:{ 
     AO:{  
    }
     Scope:fn2.[[scope]]=fnContext.AO
   }

   //調(diào)用 fn3()
   fn3Context:{
     AO:{
     } 
     Scope:fn3.[[scope]]=globalContext.AO
   }

   // 最終結(jié)果 a:undefined 5 1 6  20 200

 */

本文部分內(nèi)容來(lái)自于饑人谷寄疏,版權(quán)歸饑人谷_海瀚和饑人谷所有是牢,轉(zhuǎn)載需說(shuō)明來(lái)源

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市陕截,隨后出現(xiàn)的幾起案子驳棱,更是在濱河造成了極大的恐慌,老刑警劉巖农曲,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件社搅,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡乳规,警方通過(guò)查閱死者的電腦和手機(jī)形葬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)暮的,“玉大人笙以,你說(shuō)我怎么就攤上這事《潮纾” “怎么了猖腕?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀(guān)的道長(zhǎng)恨闪。 經(jīng)常有香客問(wèn)我倘感,道長(zhǎng),這世上最難降的妖魔是什么咙咽? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任侠仇,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘逻炊。我一直安慰自己,他們只是感情好犁享,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布余素。 她就那樣靜靜地躺著,像睡著了一般炊昆。 火紅的嫁衣襯著肌膚如雪桨吊。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,292評(píng)論 1 301
  • 那天凤巨,我揣著相機(jī)與錄音视乐,去河邊找鬼。 笑死敢茁,一個(gè)胖子當(dāng)著我的面吹牛佑淀,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播彰檬,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼伸刃,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了逢倍?” 一聲冷哼從身側(cè)響起捧颅,我...
    開(kāi)封第一講書(shū)人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎较雕,沒(méi)想到半個(gè)月后碉哑,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡亮蒋,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年扣典,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片宛蚓。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡激捏,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出凄吏,到底是詐尸還是另有隱情远舅,我是刑警寧澤,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布痕钢,位于F島的核電站图柏,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏任连。R本人自食惡果不足惜蚤吹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧裁着,春花似錦繁涂、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至桶雀,卻和暖如春矿酵,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背矗积。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工全肮, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人棘捣。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓辜腺,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親柱锹。 傳聞我的和親對(duì)象是個(gè)殘疾皇子哪自,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354

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

  • 函數(shù)聲明和函數(shù)表達(dá)式有什么區(qū)別? 函數(shù)聲明和函數(shù)表達(dá)式是EMACScript規(guī)定的兩種不同的聲明函數(shù)的方法禁熏。1.函...
    LeeoZz閱讀 347評(píng)論 0 1
  • JavaScript中的函數(shù)運(yùn)行在它們被定義的作用域里壤巷,而不是它們被執(zhí)行的作用域里。 函數(shù)聲明和函數(shù)表達(dá)式有什么區(qū)...
    畢子歌閱讀 393評(píng)論 0 0
  • 函數(shù)聲明和函數(shù)表達(dá)式有什么區(qū)別 JavaScript 中需要?jiǎng)?chuàng)建函數(shù)的話(huà)瞧毙,有兩種方法:函數(shù)聲明胧华、函數(shù)表達(dá)式,各自寫(xiě)...
    蕭雪圣閱讀 954評(píng)論 2 2
  • 1.函數(shù)聲明和函數(shù)表達(dá)式有什么區(qū)別 函數(shù)聲明 代碼執(zhí)行時(shí)函數(shù)聲明會(huì)被提升到最前執(zhí)行宙彪,所以函數(shù)的調(diào)用與函數(shù)聲明的順序...
    Feiyu_有貓病閱讀 375評(píng)論 0 0
  • 我想 要你看 看春風(fēng)拂面 嫩柳輕輕地飄舞 我想 要你聽(tīng) 聽(tīng)花開(kāi)鳥(niǎo)鳴 迎春花遍地歡唱 我想你在那花叢里 舞出你的顏色...
    虛實(shí)先森閱讀 169評(píng)論 0 9