20170418

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

  1. 函數(shù)聲明必須有標(biāo)識符,也就是常說的函數(shù)名;函數(shù)表達(dá)式可以省略函數(shù)名。
  2. 函數(shù)聲明會提前,函數(shù)聲明的話函數(shù)可以提前調(diào)用,而函數(shù)表達(dá)式是什么時候遇到什么時候執(zhí)行。
  3. 以函數(shù)聲明的方法定義的函數(shù)并不是真正的聲明,它們僅僅可以出現(xiàn)在全局中,或者嵌套在其他的函數(shù)中,但是它們不能出現(xiàn)在循環(huán),條件或者try/catch/finally中,而函數(shù)表達(dá)式可以在任何地方聲明。

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

變量提升:當(dāng)一個變量被定義時,在代碼執(zhí)行前會先將變量進(jìn)行初始化再執(zhí)行語句。函數(shù)提升:當(dāng)函數(shù)以函數(shù)聲明的方式聲明時,代碼執(zhí)行前會首先生成該函數(shù),然后再執(zhí)行語句。

arguments 是什么?

  1. 在函數(shù)代碼中,使用特殊對象 arguments,開發(fā)者無需明確指出參數(shù)名,就能訪問它們。
    例如,在函數(shù) sayHi() 中,第一個參數(shù)是 message。用 arguments[0] 也可以訪問這個值,即第一個參數(shù)的值(第一個參數(shù)位于位置 0,第二個參數(shù)位于位置 1,依此類推)。
  2. 檢測參數(shù)個數(shù)
    還可以用 arguments 對象檢測函數(shù)的參數(shù)個數(shù),引用屬性 arguments.length 即可。
    模擬函數(shù)重載

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

重載是很多面向?qū)ο笳Z言實(shí)現(xiàn)多態(tài)的手段之一,在靜態(tài)語言中確定一個函數(shù)的手段是靠方法簽名——函數(shù)名+參數(shù)列表,也就是說相同名字的函數(shù)參數(shù)個數(shù)不同或者順序不同都被認(rèn)為是不同的函數(shù),稱為函數(shù)重載。
在JavaScript中沒有函數(shù)重載的概念,函數(shù)通過名字確定唯一性,參數(shù)不同也被認(rèn)為是相同的函數(shù),后面的覆蓋前面的,但可以在函數(shù)體針對不同的參數(shù)調(diào)用執(zhí)行相應(yīng)的邏輯。
用 arguments 對象判斷傳遞給函數(shù)的參數(shù)個數(shù),即可模擬函數(shù)重載:

    function doAdd() {
      if(arguments.length == 1) {
        alert(arguments[0] + 5);
      } else if(arguments.length == 2) {
        alert(arguments[0] + arguments[1]);
      }
    }

    doAdd(10);  //輸出 "15"
    doAdd(40, 20);  //輸出 "60"

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

定義一個函數(shù),然后立即調(diào)用它。

    (function(){
      var a  = 1;
    })()

其他寫法:

    (function fn1() {});
    [function fn2() {}];
    1, function fn3() {};

作用:隔離作用域。

求n!,用遞歸來實(shí)現(xiàn)

function factor(n){
  if(n > 1){
    n = factor(n-1)*n
    return(n)
  }else{
    return(n = 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('饑人谷', 2, '男');//name:饑人谷 age:2 sex:男 ["饑人谷", 2, "男"]  name valley
getInfo('小谷', 3);//name:小谷 age:3 sex:undefined ["小谷", 3] name valley
getInfo('男');//name:男 age:undefined sex:undefined ["男"] name valley

寫一個函數(shù),返回參數(shù)的平方和?

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

如下代碼的輸出?為什么

console.log(a);//undefined
var a = 1;
console.log(b);//報(bào)錯

//實(shí)際按照如下執(zhí)行,b沒有定義故報(bào)錯。
var a;
console.log(a);
a = 1;
console.log(b);

如下代碼的輸出?為什么

sayName('world');//輸出hello world,函數(shù)的聲明會被前置
sayAge(10);//報(bào)錯,函數(shù)的表達(dá)式會被忽略掉,更不會被前置
function sayName(name){
    console.log('hello ', name);
}
var sayAge = function(age){
    console.log(age);
};
//hello world 10

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

  var x = 10
  bar() //輸出10
  function foo() {
    console.log(x)
  }
  function bar(){
    var x = 30
    foo()
  }
 //
globalContext{
  AO:{
    x = 10;
    foo:function;
    bar:function;
  }
  Scope:null;
}
//聲明 foo 時 得到下面
foo.[[scope]] = globalContext.AO
//聲明 bar 時 得到下面
bar.[[scope]] = globalContext.AO
barContext{
  AO:{
    x = 30;
  }
  Scope:bar[[scope]];//globalContext.AO
}
fooContext{
  AO:{ }
  Scope:foo[[scope]];//globalContext.AO
}

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

  var x = 10;
  bar() //輸出30
  function bar(){
    var x = 30;
    function foo(){
      console.log(x) 
    }
    foo();
  } 
 //
globalContext{
  AO:{
    x = 10;
    bar:function;
  }
  Scope:null;
}
//聲明 foo 時 得到下面
foo.[[scope]] = barContext.AO
//聲明 bar 時 得到下面
bar.[[scope]] = globalContext.AO
barContext{
  AO:{
    x = 30;
    foo:function;
  }
  Scope:bar[[scope]];//globalContext.AO
}
fooContext{
  AO:{ }
  Scope:foo[[scope]];//barContext.AO
}

以下代碼輸出什么? 寫出作用域鏈的查找過程偽代碼

  var x = 10;
  bar() //輸出30
  function bar(){
    var x = 30;
    (function (){
      console.log(x)
    })()
  }
 //
globalContext{
  AO:{
    x = 10;
    bar:function;
  }
  Scope:null;
}
//聲明 bar 時 得到下面
bar.[[scope]] = globalContext.AO
barContext{
  AO:{
    x = 30;
  }
  Scope:bar[[scope]];//globalContext.AO
}

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

  var a = 1;

  function fn(){
    console.log(a)//聲明前置。輸出undefined
    var a = 5
    console.log(a)//輸出5
    a++
    var a
    fn3()//輸出1
    fn2()//輸出6
    console.log(a)輸出20

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

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

  fn()
  console.log(a)//輸出200
//
globalContext{
  AO:{
    a = 1;
    fn:function;
    fn3:function;
  }
  Scope:null;
}
//聲明 fn 時 得到下面
fn.[[scope]] = globalContext.AO
//聲明 fn2 時 得到下面
fn2.[[scope]] = fnContext.AO
//聲明 fn3 時 得到下面
fn3.[[scope]] = globalContext.AO
fnContext{
  AO:{
    a = 5;
    fn2:function;
  }
  Scope:bar[[scope]];//globalContext.AO
}
fn3Context{
  AO:{
    a = 200; 
  }
  Scope:foo[[scope]];//globalContext.AO
}
fn2Context{
  AO:{
    a = 20; 
  }
  Scope:foo[[scope]];//fnContext.AO
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容