第十七彈-函數(shù)

問答:

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

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

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

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

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

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


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

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

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

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

相當于

      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)?;

上面的代碼相當于

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

3.arguments 是什么

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

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

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

在java中重載(overloading) 是在一個類里面,方法名字相同,而參數(shù)不同
參數(shù)不同:包括 對應位置的參數(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ù)表達式是什么?有什么作用

立即執(zhí)行表達式就是在函數(shù)定義后立即執(zhí)行;
而JavaScript引擎規(guī)定,如果function關鍵字出現(xiàn)在行首,一律解釋成語句。所以我們一般用括號括上,變成函數(shù)表達式+括號 來立即調用
立即執(zhí)行函數(shù)表達式= 函數(shù)表達式+([參數(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內部形成了一個單獨的作用域,可以封裝一些外部無法讀取的私有變量

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

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

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

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

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

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

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ù)沒有改變全局變量 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;      //遞歸調用  直到n=2 后結束 10,9,8,7,6,5,4,3,2, 
    say(n-1);
}( 10 ));  
console.log(say);    //立即執(zhí)行函數(shù)執(zhí)行完后銷毀 ,不會影響say   0
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 問答部分 一、函數(shù)聲明和函數(shù)表達式有什么區(qū)別? 二者表示函數(shù)的方式不一樣,如下 函數(shù)聲明(函數(shù)名稱不可少) 函數(shù)表...
    dengpan閱讀 494評論 0 0
  • let 命令 塊級作用域 const 命令 頂層對象的屬性 global 對象 let 命令 基本用法 ES6 新...
    嘉奇呦_nice閱讀 1,694評論 0 2
  • 三、閉包和高階函數(shù) 3.1 閉包 3.1.1 變量的作用域 所謂變量的作用域,就是變量的有效范圍。通過作用域的劃分...
    梁同學de自言自語閱讀 1,551評論 0 6
  • 函數(shù)聲明和函數(shù)表達式有什么區(qū)別 (*)解析器會率先讀取函數(shù)聲明,并使其在執(zhí)行任何代碼之前可以訪問;函數(shù)表達式則必須...
    coolheadedY閱讀 446評論 0 1
  • Oceans apart day after day 海隔一方,日復一日 I hear your voice on...
    弼馬溫老濕閱讀 650評論 2 0

友情鏈接更多精彩內容