任務(wù)17-函數(shù)

問答題

  • 函數(shù)聲明和函數(shù)表達(dá)式有什么區(qū)別 (*)
    答:

    //函數(shù)聲明
    function hello(){
        console.log("hello world");
    }
    
    //函數(shù)表達(dá)式
    var hello = function(){
        console.log("hello world");
    }
    
    

    兩種方式都能聲明函數(shù),但是函數(shù)聲明的寫法會將函數(shù)前置,可以在全局種任何地方調(diào)用函數(shù);但是表達(dá)式只能前置sayHi變量,如果在表達(dá)式之前調(diào)用函數(shù)則會報(bào)錯(cuò),只能放在表達(dá)式后面進(jìn)行調(diào)用。

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

    • 變量的聲明前置:變量聲明都會被放在代碼的頭部,只提升變量的聲明并不會進(jìn)行賦值。
    //全局中定義變量
    var a = 1;
    var b = 2;
    //實(shí)際是執(zhí)行起來是這樣的
    var a;
    var b;
    a = 1;
    b = 2;
    
    //函數(shù)中
    function say(){
        var a = 1;
        console.log(a);
        var b = 2;
    }
    //實(shí)際運(yùn)行過程
    function say(){
        var a;
        var b;
        a = 1;
        console.log(a);
        b = 2;
    }
    
    • 函數(shù)聲明前置:函數(shù)的聲明前置和變量聲明一樣,會提升到代碼頭部。但是會提升到變量聲明后面,所以可以在函數(shù)聲明前面調(diào)用函數(shù)。
     f(10);//10     此時(shí)該函數(shù)是有效的,且結(jié)果正確
    function f(num){
        console.log(num);
    }
    

    相當(dāng)于

    function f(num){
       cconsole.log(num);
    }
    f(10);
    
  • arguments 是什么 (*)
    答:
    Arguments是個(gè)類似數(shù)組但不是數(shù)組的對象,說他類似數(shù)組是因?yàn)槠渚邆鋽?shù)組相同的訪問性質(zhì)及方式,能夠由arguments[n]來訪問對應(yīng)的單個(gè)參數(shù)的值,并擁有數(shù)組長度屬性length。還有就是arguments對象存儲的是實(shí)際 傳遞給函數(shù)的參數(shù),而不局限于函數(shù)聲明所定義的參數(shù)列表,而且不能顯式創(chuàng)建 arguments 對象。


    Paste_Image.png

    arguments對象的長度是由實(shí)參決定的。

  • 函數(shù)的重載怎樣實(shí)現(xiàn) (**)
    答:
    在JavaScript中沒有函數(shù)重載的概念,函數(shù)通過名字確定唯一性,參數(shù)不同也被認(rèn)為是相同的函數(shù),后面的覆蓋前面的。函數(shù)調(diào)用沒必要把所有參數(shù)都傳入,只要你函數(shù)體內(nèi)做好處理就行,但前提是傳的參數(shù)永遠(yuǎn)被當(dāng)做前幾個(gè)。


    Paste_Image.png
  • 立即執(zhí)行函數(shù)表達(dá)式是什么?有什么作用 (***)
    答:

    (function(){
        //第一種
    })();
    
    (function(){
        //第二種
    }());
    

    作用是:立即執(zhí)行函數(shù)可以避免函數(shù)內(nèi)的變量暴露在全局環(huán)境下,避免全局變量的污染。可以令其函數(shù)中聲明的變量繞過JavaScript的變量置頂聲明規(guī)則,還可以避免新的變量被解釋成全局變量或函數(shù)名占用全局變量名的情況,在函數(shù)內(nèi)部內(nèi)部形成了一個(gè)單獨(dú)的作用域,可以封裝一些外部無法讀取的私有變量。

  • 什么是函數(shù)的作用域鏈 (****)
    答:
    在一個(gè)函數(shù)執(zhí)行過程中如果某個(gè)變量在該函數(shù)自己的作用域中沒有,那么它會尋找父級的作用域,直到全局作用域,這樣就形成了一個(gè)作用域鏈。


    Paste_Image.png

    執(zhí)行ss()時(shí),作用域鏈?zhǔn)牵?ss()->t()->window,所以name是”桶飯"

代碼題

  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, '男');
    getInfo('hunger', 28);
    getInfo('男');
    

輸出結(jié)果:


Paste_Image.png

形參和實(shí)參的數(shù)量可以不一樣,用arguments可以改變實(shí)參的值。

  1. 寫一個(gè)函數(shù),返回參數(shù)的平方和?如 (難度**)

       function sumOfSquares(){
       var num;
       for(var i = 0;i<arguments.length;i++){
         
         num = num+arguments[i]*arguments[i];
       }
      return num;
       
    }
     sumOfSquares(2,3,4);   // 29
     sumOfSquares(1,3);
    
  2. 如下代碼的輸出?為什么 (難度*)

    console.log(a);
    var a = 1;
    console.log(b);
    
    //運(yùn)算過程
    var a;
    console.log(a);//輸出undefined,因?yàn)樽兞刻嵘瑫炎兞縜的聲明提升到console.log(a);之前,當(dāng)console.log(a);執(zhí)行的時(shí)候,變量a還沒有被賦值,所以console.log(a);輸出undefined。
    a = 1;
    console.log(b);//報(bào)錯(cuò),因?yàn)闆]有變量b。
    

    輸出結(jié)果:

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

    sayName('world');
    sayAge(10);
    function sayName(name){
        console.log('hello ', name);
    }
    var sayAge = function(age){
        console.log(age);
    };
    
    //運(yùn)算過程
    //在執(zhí)行上面代碼的時(shí)候會將函數(shù)的聲明前置,而函數(shù)表達(dá)式只會將變量的聲明前置,函數(shù)不會前置。實(shí)際上述代碼在執(zhí)行的時(shí)候會變成這樣:
    var sayAge;
    function sayName(name){
        console.log('hello ', name);
    }
    sayName('world');
    sayAge(10);//sayAge(10);的時(shí)候,sayAge只是個(gè)變量不是函數(shù),所以會報(bào)錯(cuò)。最終會輸出hello world和報(bào)錯(cuò)。
    sayAge = function(age){
        console.log(age);
    };
    
    
    Paste_Image.png
  2. 如下代碼的輸出?為什么 (難度**)

    function fn(){}
        var fn = 3;
        console.log(fn);//輸出3
        //當(dāng)在同一個(gè)作用域內(nèi)定義了名字相同的變量和方法的話,無論其順序如何,變量的賦值會覆蓋方法的賦值。
    
  3. 如下代碼的輸出?為什么 (難度***)

        function fn(fn2){
           console.log(fn2);
           var fn2 = 3;
           console.log(fn2);
           console.log(fn);
           function fn2(){
                console.log('fnnn2');
            }
         }
        fn(10);
    

輸出:


Paste_Image.png
   //過程
   function fn(fn2){
   
   var fn2;//變量聲明前置
   function fn2(){
         console.log('fnnn2');
     }//函數(shù)聲明前置
   console.log(fn2);//log fn2()函數(shù)
   fn2 = 3;//賦值
   console.log(fn2);//log fn2  此時(shí) fn2是3
   console.log(fn);//此作用域找不到 fn,向上尋找打印 fn 函數(shù)
   
   }
   fn(10);
   //函數(shù)執(zhí)行命名有沖突的時(shí)候,函數(shù)執(zhí)行載入順序是變量、函數(shù)、參數(shù)
   ```

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

   ```
   var fn = 1;
   function fn(fn){
       console.log(fn);
   }
   console.log(fn(fn)); 
   ```
   輸出:
   ![Paste_Image.png](http://upload-images.jianshu.io/upload_images/2858982-ab080b605e1f5adb.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

   因?yàn)榻o變量聲明進(jìn)行賦值操作后,同名的變量聲明的優(yōu)先級會大于同名函數(shù)聲明,會覆蓋同名的函數(shù)聲明,所以fn現(xiàn)在是一個(gè)變量不是函數(shù),執(zhí)行函數(shù)fn就會報(bào)錯(cuò)。

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

   ```
   //作用域
   console.log(j);//輸出undefined,因?yàn)樽兞柯暶髑爸茫琲這時(shí)候還沒有賦值。
   console.log(i);//輸出undefined,因?yàn)樽兞柯暶髑爸茫琷這時(shí)候還沒有賦值。
   for(var i=0; i<10; i++){
      var j = 100;
   }
   console.log(i);//輸出10,因?yàn)閒or循環(huán)語句結(jié)束循環(huán)時(shí),i的值是10 。
   console.log(j);//輸出100,應(yīng)為變量j的值是100。
   ```
   輸出:
   ![Paste_Image.png](http://upload-images.jianshu.io/upload_images/2858982-dad462fcdf2280d3.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

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

   ```
   fn();
   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;
      }
   }
   ```
   
   ```
   //過程
   var i;
   var fn;
   
   function fn() {
   
      var i;
   
      function fn2() {
          i = 100;
      }
      console.log(i);// 輸出undefined,因?yàn)樽兞縤的聲明前置,但還沒有賦值。
      i = 99;
      fn2();//執(zhí)行函數(shù)fn2,因?yàn)楹瘮?shù)中的變量i沒有加關(guān)鍵字var,所以它是一個(gè)全局變量,它會把100賦值到函數(shù)fn的變量i。這時(shí)i=100
      console.log(i);//輸出100,因?yàn)樽兞縤的值為100。
   }
   fn();
   i = 10;
   fn = 20;
   console.log(i);//輸出10,因?yàn)樽詈笞兞縤的值是10。
   ```
   ![Paste_Image.png](http://upload-images.jianshu.io/upload_images/2858982-a755443ab6d14c20.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

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

   ```
   var say = 0;
   (function say(n){ //立即執(zhí)行函數(shù),給函數(shù)初始的參數(shù)n=10,當(dāng)滿足n<3時(shí),執(zhí)行say(n-1)。
      console.log(n);//輸出10,9,8,7,6,5,4,3,2,因?yàn)楫?dāng)n=2時(shí),函數(shù)return。
      if(n<3) return;
      say(n-1);
   }( 10 ));
   console.log(say);//輸出0.因?yàn)榱⒓磮?zhí)行函數(shù)say(n)相當(dāng)于創(chuàng)造了一塊私有的作用域,函數(shù)say(n)內(nèi)部可以訪問外部的變量,而外部環(huán)境不能訪問函數(shù)say(n)內(nèi)部的變量,內(nèi)部定義的變量不會和外部的變量發(fā)生沖突,所以變量say一直等于0。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

  • 1.函數(shù)聲明和函數(shù)表達(dá)式有什么區(qū)別 (*) 函數(shù)聲明 函數(shù)表達(dá)式 函數(shù)聲明:函數(shù)調(diào)用可以發(fā)生在函數(shù)聲明之前,例如下...
    TimeLesser閱讀 403評論 4 4
  • 問答: 1. 函數(shù)聲明和函數(shù)表達(dá)式有什么區(qū)別 (*) 在日常的任務(wù)中,JavaScript主要使用下面兩種方式創(chuàng)建...
    小木子2016閱讀 324評論 0 0
  • 函數(shù)聲明和函數(shù)表達(dá)式有什么區(qū)別 (*)解析器會率先讀取函數(shù)聲明,并使其在執(zhí)行任何代碼之前可以訪問;函數(shù)表達(dá)式則必須...
    coolheadedY閱讀 399評論 0 1
  • 1.函數(shù)聲明和函數(shù)表達(dá)式的區(qū)別? 在ECMAScript中,創(chuàng)建函數(shù)的最常用的兩個(gè)方法是函數(shù)表達(dá)式和函數(shù)聲明,兩者...
    GarenWang閱讀 545評論 0 0
  • 關(guān)于模仿 看到這個(gè)詞,你的第一反應(yīng)是什么? 反感? 厭惡? 嗤之以鼻? 冷靜下來!思考一下,哪個(gè)人能離開這個(gè)詞? ...
    淡定的小孩兒閱讀 217評論 0 2