進(jìn)階3

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

  • 使用函數(shù)聲明來聲明的函數(shù)不需要放在調(diào)用的前面就可以被調(diào)用,使用函數(shù)表達(dá)式聲明的函數(shù)需要放在調(diào)用函數(shù)的前面才能被正確調(diào)用。

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

  • 在一個(gè)作用域下,var 聲明的變量和function 聲明的函數(shù)會(huì)前置。
  • 使用var聲明的變量會(huì)在執(zhí)行代碼的時(shí)候先預(yù)解析到作用域的頭部,并被賦值為undefined.
  • 使用function聲明的函數(shù)也一樣會(huì)被預(yù)解析讀取到作用域的頭部。

3.arguments 是什么

  • arguments是一個(gè)函數(shù)自帶的參數(shù)對(duì)象,他包含了函數(shù)所有的參數(shù),而且可以像調(diào)用一個(gè)數(shù)組一樣來調(diào)用,不過arguments并不是一個(gè)數(shù)組,如果用typeof來檢測(cè)的話會(huì)返回"object",表示是一個(gè)對(duì)象。

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

  • 重載在一般的編程語言中,表示有相同的函數(shù)名,但是參數(shù)列表不相同,通過傳遞不同的參數(shù)可以讓函數(shù)內(nèi)部的處理方法不一樣,得到也結(jié)果也可能不同。
  • JaveScript中并沒有重載,函數(shù)同名的話會(huì)被覆蓋,但可以在函數(shù)體針對(duì)不同的參數(shù)調(diào)用執(zhí)行相應(yīng)的邏輯。
  function printPeopleInfo(name, age, sex){
    if(name){
      console.log(name);
    }

    if(age){
      console.log(age);
    }

    if(sex){
      console.log(sex);
    }
  }

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

  • 立即執(zhí)行函數(shù)表達(dá)式表示直接聲明函數(shù),聲明后直接調(diào)用函數(shù)。不直接在聲明函數(shù)直接加上‘()’調(diào)用時(shí)因?yàn)闉g覽器不識(shí)別會(huì)報(bào)語法錯(cuò)誤。一般寫法為直接將聲明函數(shù)用小括號(hào)括起來然后再在后面添加上小括號(hào)調(diào)用。
  • 作用是可以隔離作用域,防止污染全局作用域。

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

function fn(n){
    if (n === 1){
        return 1;
}
   return n*fn(n-1);
}
   fn(n)

7.以下代碼輸出什么?

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

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

   function sumOfSquares(){
        if (arguments.length === 0){
             alert("請(qǐng)輸入至少一個(gè)參數(shù)")
         }
         var sum = 0;
       for(var i=0;i<arguments.length;i++){
                sum += arguments[i]*arguments[i];
        }
             return  sum;
   }
   var result = sumOfSquares(2,3,4)
   var result2 = sumOfSquares(1,3)
   console.log(result)  //29
   console.log(result2)  //10

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

    console.log(a);  //undefined
    var a = 1;
    console.log(b);   // 報(bào)錯(cuò)
  • 因?yàn)樽兞柯暶髑爸玫年P(guān)系,var a 會(huì)被提到作用域頭部,賦值為undefined,然后運(yùn)行到代碼的時(shí)候會(huì)被賦值為1.而變量b并沒有被聲明,函數(shù)運(yùn)行到代碼console.log(b); 時(shí)在作用域內(nèi)找不到變量b,所以瀏覽器報(bào)錯(cuò)。

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

    sayName('world');    //hello world
    sayAge(10);  //  瀏覽器報(bào)錯(cuò) sayAge is not a function
    function sayName(name){
        console.log('hello ', name);
    }
    var sayAge = function(age){
        console.log(age);
    };
  • 使用函數(shù)聲明方式來聲明的函數(shù),會(huì)因?yàn)楹瘮?shù)聲明前置被提到作用域的頭部,所以調(diào)用sayName時(shí)即使調(diào)用函數(shù)寫在聲明函數(shù)之前依舊有效果,但是使用函數(shù)表達(dá)式聲明函數(shù)的話,瀏覽器會(huì)先解析sayAge為一個(gè)變量,并賦值為undefined然后提到代碼頭部,然后執(zhí)行到聲明函數(shù)的代碼時(shí)才會(huì)將這個(gè)變量賦值為一個(gè)函數(shù)。調(diào)用寫在聲明之前的話瀏覽器執(zhí)行到調(diào)用函數(shù)的代碼段時(shí)會(huì)認(rèn)為sayAge是一個(gè)變量,使用函數(shù)調(diào)用方式是錯(cuò)誤的,從而報(bào)錯(cuò)。

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

var x = 10
bar()  // x= 10
function foo() {
  console.log(x)
}
function bar(){
  var x = 30
  foo()
}
==>
/*
globalContext = {
        AO:{
               x:10;
               foo: function(){}
               bar: function(){}
                }
               scope:null;
            }
barContext = {
      AO:{
            x:30;
         }
      bar.[[scope]]  =globalContext.AO
}
fooContext = {
      AO:{
         }
      foo.[[scope]]  =globalContext.AO
}
*/
  • foo.scope為全局作用域,當(dāng)執(zhí)行bar時(shí)會(huì)現(xiàn)在bar的函數(shù)作用域bar.AO中創(chuàng)建一個(gè)x并被賦值為30,然后調(diào)用函數(shù)foo,在foo的作用域中找不到變量x,所以會(huì)返回到foo.scope中也就是全局作用域中尋找,得到x=10。

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

var x = 10;
bar()       //  30
function bar(){
  var x = 30;
  function foo(){
    console.log(x) 
  }
  foo();
}   
==>
/*
globalContext = {
        AO:{
               x:10             
               bar: function(){}
                }
               scope:null;
            }
barContext = {
      AO:{
            x:30;
            foo: function(){}
         }
      bar.[[scope]]  =globalContext.AO
}
fooContext = {
      AO:{
         }
      foo.[[scope]]  =barContext.AO
}
*/
  • 和上一題差不多,不過這題中foo.scope為barContext.AO,所以x值去barContext.AO里面找,找到x為30
  1. 以下代碼輸出什么? 寫出作用域鏈的查找過程偽代碼
var x = 10;
bar()          // 30
function bar(){
  var x = 30;
  (function (){
    console.log(x)
  })()
}
==>
/*globalContext = {
  AO: {
    x: 10
    bar: function
  }
  Scope: null
}

barContext = {
  AO: {
    x: 30
    function: function
  }
  Scope: globalContext.AO
}

functionContext = {
  AO: {}
  Scope: barContext.AO
}
*/
  • 與上一題差不多,只不過這里沒有聲明函數(shù)再調(diào)用,而是立即執(zhí)行函數(shù)表達(dá)式的寫法,函數(shù)的執(zhí)行上下文依然還是barContext.AO,所以取到的x的值依舊是30。

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

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()        // undefined  5   1  6  20
console.log(a)   // 200
==>
/*
globalContext = {
  AO: {
    x: 1
    fn: function
    fn3:function
  }
  Scope: null
}
fnContext = {
  AO: {
    a: undefined
    a:5
    a:6
    fn2:function
  }
  Scope: globalContext.AO
}
fn2Context = {
  AO: {
    a:20
  }
  Scope: fnContext.AO
}
fn3Context = {
  AO: {
    a:200
  }
  Scope: globalContext.AO
}
*/
  • 調(diào)用fn時(shí),因?yàn)樽兞壳爸茫缘谝粋€(gè)console.log(a)得到undefined,然后a被賦值為5,第二次console.log(a)得到 a=5,之后執(zhí)行a++ 使a=6.
  • 接著調(diào)用fn3,但是fn3中console.log(a)在a=200之前,且并沒有使用var讓變量聲明前置,找不到變量a,便會(huì)去fn3的執(zhí)行上下文中也就是全局作用域中尋找,得到a=1;然后再將全局作用域中的a賦值為200.
  • 然后調(diào)用fn2,console.log(a)在a=20之前,但是依然沒有變量前置,所以會(huì)在fn2的執(zhí)行上下文fnContext.AO中尋找,得到a=6,然后降fnContext.AO中的a賦值為20.
  • 最后一次console.log(a)調(diào)用得到的a = 20.到此fn執(zhí)行完畢。
  • fn調(diào)用后執(zhí)行的console.log(a),因?yàn)橹叭肿饔糜虻腶 在執(zhí)行fn3是被賦值成了200,所以得到200
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 1.函數(shù)聲明和函數(shù)表達(dá)式有什么區(qū)別 函數(shù)聲明 代碼執(zhí)行時(shí)函數(shù)聲明會(huì)被提升到最前執(zhí)行,所以函數(shù)的調(diào)用與函數(shù)聲明的順序...
    Feiyu_有貓病閱讀 483評(píng)論 0 0
  • 1.函數(shù)聲明和函數(shù)表達(dá)式有什么區(qū)別 函數(shù)聲明使用function關(guān)鍵字可以聲明一個(gè)函數(shù) 聲明不必放到調(diào)用的前面; ...
    饑人谷_瀟湘情緒雨閱讀 212評(píng)論 0 0
  • 有一個(gè)勇士,在他被稱為勇士之前,他是小勇。小勇的女朋友叫小美,當(dāng)然小美是很美的,美,并不總是好事,美人被稱為禍水的...
    趙安歌閱讀 365評(píng)論 0 1
  • 我愛你 就像那年的雨季, 遙遠(yuǎn)而又漫長(zhǎng)。 我討厭你 更加討厭喜歡你的我。
    伊一ing閱讀 166評(píng)論 0 0
  • 有那么一個(gè)姑娘,每天吃吃喝喝鬧鬧,看見誰都是哈哈哈三聲大笑,卻總是在夜半人靜的時(shí)候,一個(gè)人抱著喜歡的公仔大冬天在鋪...
    瘋子蘇小柒閱讀 853評(píng)論 0 49

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