函數與作用域、函數重載

1.函數聲明和函數表達式有什么區別

  • 函數聲明可以看作是函數的初始化,我們將給函數傳參并建立函數體的表達式,當我門建立完成后,就可以進行函數的表達式了,做法如下:function foo(){}, foo();
  • 函數表達式其實就是創建一個匿名的函數聲明并賦值給一個變量,如var foo = function () {}。
  • 區別:
  • 函數聲明:不需要放置在函數調用前面
  • 函數表達式:必須將函數放置在函數調用前面

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

  1. 變量聲明的前置:

         console.log(i);
         var i = 1;
    

那么輸出的結果將是undefined,因為:

        var i;(因為提前了而且未被賦值).
        console.log(i);
        i =1;(到了這里之前的i才被賦值,再輸出一次就為1了)
  1. 是函數的聲明前置
    test(1)
    function test(x){console.log(x);}
    輸出的結果其實為1;因為function test(x){...}的整個函數已經提前到了test(1)之前。
    但是,值得注意的是,同樣的方法,如果使用在函數表達式上的話,其出現的結果往往可能是報錯,因為調用在其聲明之前,相當于變量聲明前置了。

3.arguments 是什么?

  • Arguments是個類似數組但不是數組的對象,說他類似數組是因為其具備數組相同的訪問性質及方式,能夠由arguments[n]來訪問對應的單個參數的值,并擁有數組長度屬性length。

4.函數的"重載"怎樣實現?

  • javascript不支持函數重載,不能夠定義同樣的函數然后通過編譯器去根據不同的參數執行不同的函數。
    但是javascript卻可以通過自身屬性去模擬函數重載。
    直接上例子,比較簡單的實現方法:
    function calculate() {
    if (arguments.length == 2) {
    return arguments[0] + arguments[1];
    }
    if (arguments.length == 3) {
    return arguments[0] * arguments[1] * arguments[2];
    }
    }

    alert(calculate(1, 3))
    

js函數重載

5.立即執行函數表達式是什么?有什么作用?

  • 立即執行函數就是當我們在定義了函數之后需要立即執行的函數

      function(){ /* code */ }();// SyntaxError: Unexpected token (
    
  • 一般情況下,也許有人認為立即執行函數可能會是這個樣子的,但其實為了避免解析上的歧義,JavaScript引擎規定,如果function關鍵字出現在行首,一律解釋成語句。因此,JavaScript引擎看到行首是function關鍵字之后,認為這一段都是函數的定義,不應該以圓括號結尾,所以就報錯了。

  • 所以一般情況下,在寫,IIFE的時候要寫成:

      (function(){ /* code */ }());
      // 或者
      (function(){ /* code */ })();
    
  • 上面兩種寫法都是以圓括號開頭,引擎就會認為后面跟的是一個表示式,而不是函數定義語句,所以就避免了錯誤。這就叫做“立即調用的函數表達式”(Immediately-Invoked Function Expression),簡稱IIFE。

  • 注意,上面兩種寫法最后的分號都是必須的。如果省略分號,遇到連著兩個IIFE,可能就會報錯。

  • 推而廣之,任何讓解釋器以表達式來處理函數定義的方法,都能產生同樣的效果,比如下面三種寫法。

    var i = function(){ return 10; }();
    
    true && function(){ /* code */ }();
    
    0, function(){ /* code */ }();
    
  • 作用:
    通常情況下,只對匿名函數使用這種“立即執行的函數表達式”。它的目的有兩個:一是不必為函數命名,避免了污染全局變量;二是IIFE內部形成了一個單獨的作用域,可以封裝一些外部無法讀取的私有變量。

6.求n!,用遞歸來實現

n!.png

7.以下代碼輸出什么?

  1. getInfo('饑人谷', 2, '男');

     輸出: name:饑人谷、age:2、sex:男、['饑人谷', 2, '男']、name:vally;
    
  2. getInfo('小谷', 3);

     輸出: name:小谷、age:3、undefined、['小谷', 3]、name:vally;
    
  3. getInfo('男');

     輸出: name:男、undefined、undefined、['男']、name:vally;
    

8.寫一個函數,返回參數的平方和?

平方和.png

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

  console.log(a);
  var a = 1;
  console.log(b);
  • 第一個輸出為undefined因為變量聲明前置原因導致
  • 第二個輸出報錯(b is not defined),因為沒有聲明變量

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

  sayName('world');
  sayAge(10);
  function sayName(name){
      console.log('hello ', name);
  }
  var sayAge = function(age){
      console.log(age);
  };
  • sayName('world')輸出為hello world,函數聲明聲明前置原因
  • sayAge(10)輸出報錯(b is not defined),因為沒有聲明變量

11.如下代碼輸出什么? 寫出作用域鏈查找過程偽代碼

11.png

12.如下代碼輸出什么? 寫出作用域鏈查找過程偽代碼

12.png

13.如下代碼輸出什么? 寫出作用域鏈查找過程偽代碼

13.png

14.如下代碼輸出什么? 寫出作用域鏈查找過程偽代碼

14.png

15.如下代碼輸出什么? 寫出作用域鏈查找過程偽代碼

  • 所有變量均為全局變量
15.png
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 1.函數聲明和函數表達式有什么區別 函數就是一段可以反復調用的代碼塊。函數還能接受輸入的參數,不同的參數會返回不同...
    徐國軍_plus閱讀 492評論 0 0
  • 聲明前置和作用域也是JS 部分面試??键c 1.函數聲明和函數表達式有什么區別 函數聲明:使用function關鍵字...
    湖衣閱讀 210評論 0 0
  • 函數聲明和函數表達式有什么區別 (*)解析器會率先讀取函數聲明,并使其在執行任何代碼之前可以訪問;函數表達式則必須...
    coolheadedY閱讀 400評論 0 1
  • 目錄 從零實現ImageLoader(一)—— 架構從零實現ImageLoader(二)—— 基本實現從零實現Im...
    GavinLi369閱讀 956評論 0 11
  • 夢蝶 只因, 風的無骨之柔, 你翩翩復翩翩, 飛臨我的夢境。 想象的風月, 從萬水千山而來, 又復歸原始的...
    冰雪幽人閱讀 284評論 0 0