函數(shù)與作用域

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

函數(shù)聲明使用function關(guān)鍵字聲明一個(gè)函數(shù),function fn() { },函數(shù)聲明必須始終帶有一個(gè)標(biāo)識符即函數(shù)名擎椰,函數(shù)聲明會在任何表達(dá)式被解析和求值之前先行被解析和求值逻住,函數(shù)可以在任意地方調(diào)用fn()钟哥,聲明不必放到調(diào)用的前面。
函數(shù)表達(dá)式通過賦值來聲明函數(shù)瞎访,聲明完畢后要加上分號表示該句結(jié)束腻贰,聲明必須放到調(diào)用的前面,在表達(dá)式執(zhí)行完后扒秸,函數(shù)才存在并可被調(diào)用播演。

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

在一個(gè)作用域下伴奥,var 聲明的變量和function 聲明的函數(shù)會前置写烤。
javascript引擎的工作方式是,先解析代碼拾徙,獲取所有被聲明的變量洲炊,然后再一行一行地運(yùn)行。變量聲明前置就是在一個(gè)作用域中尼啡,所有的變量都被放在開始處聲明暂衡,即使聲明位于源代碼中的最后一行,它也會先于同一作用域中位于最前面的表達(dá)式執(zhí)行崖瞭。

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

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

JavaScript引擎將函數(shù)名視同變量名狂巢,所以采用function命令聲明函數(shù)時(shí),整個(gè)函數(shù)會像變量聲明一樣书聚,被提升到代碼頭部唧领。函數(shù)的聲明前置是在一個(gè)作用域中藻雌,函數(shù)的聲明會被放在代碼開始處先執(zhí)行。而函數(shù)內(nèi)部的聲明前置則指的是在執(zhí)行該函數(shù)里面的語句的時(shí)候疹吃,聲明會被首先執(zhí)行蹦疑。

3.arguments 是什么

arguments 是JavaScript里的一個(gè)內(nèi)置對象,是比較特別的一個(gè)對象,在js中在調(diào)用一個(gè)函數(shù)的時(shí)候萨驶,我們經(jīng)常會給這個(gè)函數(shù)傳遞一些參數(shù)歉摧,js把傳入到這個(gè)函數(shù)的全部參數(shù)存儲在arguments里,在函數(shù)內(nèi)部,可以使用arguments對象獲取到該函數(shù)的所有傳入?yún)?shù)腔呜。

function printPersonInfo(name, age, sex){
    console.log(name);
    console.log(age);
    console.log(sex);
    console.log(arguments);
  }

它的屬性名是按照傳入?yún)?shù)的序列來的叁温,第1個(gè)參數(shù)的屬性名是0,第2個(gè)參數(shù)的屬性名是1核畴,以此類推膝但,并且它還有l(wèi)ength屬性,存儲的是當(dāng)前傳入函數(shù)參數(shù)的個(gè)數(shù)谤草,很多時(shí)候我們把這種對象叫做類數(shù)組對象跟束。

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

重載是很多面向?qū)ο笳Z言實(shí)現(xiàn)多態(tài)的手段之一,在靜態(tài)語言中確定一個(gè)函數(shù)的手段是靠方法簽名——函數(shù)名+參數(shù)列表丑孩,也就是說相同名字的函數(shù)參數(shù)個(gè)數(shù)不同或者順序不同都被認(rèn)為是不同的函數(shù)冀宴,稱為函數(shù)重載。在JavaScript中沒有函數(shù)重載的概念温学,函數(shù)通過名字確定唯一性略贮,參數(shù)不同也被認(rèn)為是相同的函數(shù),后面的覆蓋前面的仗岖,但可以在函數(shù)體針對不同的參數(shù)調(diào)用執(zhí)行相應(yīng)的邏輯逃延。在函數(shù)定義中用f.arguments.length判斷一下調(diào)用時(shí)傳入的參數(shù)個(gè)數(shù)。然后對不同的情況采用不同的處理方式轧拄。

function printPeopleInfo(name, age, sex){
    if(name){
      console.log(name);
    }

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

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


  printPeopleInfo('Byron', 26);
  printPeopleInfo('Byron', 26, 'male');

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

立即執(zhí)行函數(shù)表達(dá)式就是聲明一個(gè)匿名函數(shù),馬上調(diào)用這個(gè)匿名函數(shù)。

(function(){
  var a  = 1;
})()
console.log(a); //undefined

其他寫法

(function fn1() {});
 
// 在數(shù)組初始化器內(nèi)只能是表達(dá)式
[function fn2() {}];
 
// 逗號也只能操作表達(dá)式
1, function fn3() {};

作用:不必為函數(shù)命名紧帕,避免了污染全局變量盔然,隔離作用域,創(chuàng)建一個(gè)獨(dú)立的作用域是嗜,這個(gè)作用域里面的變量,外面訪問不到(即避免「變量污染」)挺尾。

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

function factor(n){
  if(n === 1|| n === 0) {
    return 1
  }
  return n * factor(n-1)
}
factor(5)

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, '男');
getInfo('小谷', 3);
getInfo('男');

輸出

name: 饑人谷
age: 2
sex: 男
['饑人谷', 2, '男']
name valley
name: 小谷
age: 3
sex: undefined
['小谷',3]
name valley
name: 男
age: undefined
sex: undefined
["男"]
name valley

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

   function sumOfSquares(){
     var sum = 0;
     for(var n = 0;n<arguments.length;n++{
       sum = sum+arguments[n]*arguments[n];
     }
     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,相當(dāng)于var a聲明前置甫题,輸出undefined,再a=1
    var a = 1;
    console.log(b);//error,報(bào)錯(cuò)馁筐,b沒聲明

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

    sayName('world');
    sayAge(10);
    function sayName(name){
        console.log('hello ', name);
    }
    var sayAge = function(age){
        console.log(age);
    };

輸出

hello world//函數(shù)聲明不必放在調(diào)用前坠非,函數(shù)聲明前置
error//函數(shù)表達(dá)式須放在調(diào)用前面敏沉,函數(shù)表達(dá)式只有執(zhí)行到這一行才會去聲明

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

var x = 10
bar() 
function foo() {
  console.log(x)
}
function bar(){
  var x = 30
  foo()
}
1.
globalContext = {
  AO: {
    x: 10
    foo: function
    bar: function
  },
  Scope: null
}

foo.[[scope]] = globalContext.AO
bar.[[scope]] = globalContext.AO
2.調(diào)用bar()
    barContext = {
        AO:{
            x:30
        },
        Scope:bar.[[scope]] = globalContext.AO
    }
 3.調(diào)用foo()
    fooContext = {
        AO:{},
        Scope:foo.[[scope]] = globalContext.AO
    }
    輸出10

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

var x = 10;
bar() 
function bar(){
  var x = 30;
  function foo(){
    console.log(x) 
  }
  foo();
}   
1.
globalContext = {
  AO: {
    x: 10
    bar: function
  },
  Scope: null
}
bar.[[scope]] = globalContext.AO
2.調(diào)用bar()
    barContext = {
        AO:{
            x:30
            foo:function
        },
        Scope:bar.[[scope]] = globalContext.AO
    }
   foo.[[scope]] = barContext.AO

 3.調(diào)用foo()
    fooContext = {
        AO:{},
        Scope:foo.[[scope]] = barContext.AO
    }
    輸出30

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

var x = 10;
bar() 
function bar(){
  var x = 30;
  (function (){
    console.log(x)
  })()
}
1.
globalContext = {
  AO: {
    x: 10
    bar: function
  },
  Scope: null
}
bar.[[scope]] = globalContext.AO
2.調(diào)用bar()
    barContext = {
        AO:{
            x:30
            function(){}
        },
        Scope:bar.[[scope]] = globalContext.AO
    }
   function.[[scope]] = barContext.AO

 3.調(diào)用立即執(zhí)行函數(shù)
    functionContext = {
        AO:{},
        Scope:function.[[scope]] = barContext.AO
    }
    輸出30

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

var a = 1;

function fn(){
  console.log(a)//undefined
  var a = 5//fncontext.AO中的a賦值為5
  console.log(a)//輸出5
  a++//fnContext.AO中的a加1為6
  var a
  fn3()//調(diào)用fn3()炎码,去執(zhí)行fn3()
  fn2()//調(diào)用fn2()
  console.log(a)//此時(shí)fnContext.AO中的a賦值為20盟迟,輸出20

  function fn2(){
    console.log(a)//此時(shí)fnContext.AO中的a賦值為6,所以輸出6
    a = 20//fnContext.AO中的a賦值為20
  }
}

function fn3(){
  console.log(a)//因?yàn)閒n3Context.AO中沒有a值潦闲,所以去globalContext.AO找攒菠,a值為1,所以輸出1
  a = 200//globalContext.AO中a賦值為200
}

fn()
console.log(a))//此時(shí)globalContext.AO中a賦值為200
1.
globalContext = {
  AO: {
    a: 1 200
    fn: function
    fn3:function
  },
  Scope: null
}
fn.[[scope]] = globalContext.AO
fn3.[[scope]] = globalContext.AO

2.調(diào)用fn()
fnContext = {
  AO: {
    a: undefined 5 6 20
    fn2: function
  },
  Scope: fn.[[scope]] = globalContext.AO
}
fn2.[[scope]] = fnContext.AO
3.調(diào)用fn3()
fn3Context = {
  AO: { },
  Scope: fn3.[[scope]] = globalContext.AO
}
4.調(diào)用fn2()
fn2Context = {
  AO: { },
  Scope: fn2.[[scope]] = fnContext.AO
}
輸出:undefined 5 1 6 20 200
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末歉闰,一起剝皮案震驚了整個(gè)濱河市辖众,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌和敬,老刑警劉巖凹炸,帶你破解...
    沈念sama閱讀 211,817評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異概龄,居然都是意外死亡还惠,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評論 3 385
  • 文/潘曉璐 我一進(jìn)店門私杜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蚕键,“玉大人,你說我怎么就攤上這事衰粹÷喙猓” “怎么了?”我有些...
    開封第一講書人閱讀 157,354評論 0 348
  • 文/不壞的土叔 我叫張陵铝耻,是天一觀的道長誊爹。 經(jīng)常有香客問我,道長瓢捉,這世上最難降的妖魔是什么频丘? 我笑而不...
    開封第一講書人閱讀 56,498評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮泡态,結(jié)果婚禮上搂漠,老公的妹妹穿的比我還像新娘。我一直安慰自己某弦,他們只是感情好桐汤,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,600評論 6 386
  • 文/花漫 我一把揭開白布而克。 她就那樣靜靜地躺著,像睡著了一般怔毛。 火紅的嫁衣襯著肌膚如雪员萍。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,829評論 1 290
  • 那天拣度,我揣著相機(jī)與錄音碎绎,去河邊找鬼。 笑死蜡娶,一個(gè)胖子當(dāng)著我的面吹牛混卵,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播窖张,決...
    沈念sama閱讀 38,979評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼幕随,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了宿接?” 一聲冷哼從身側(cè)響起赘淮,我...
    開封第一講書人閱讀 37,722評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎睦霎,沒想到半個(gè)月后梢卸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,189評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡副女,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,519評論 2 327
  • 正文 我和宋清朗相戀三年蛤高,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片碑幅。...
    茶點(diǎn)故事閱讀 38,654評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡戴陡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出沟涨,到底是詐尸還是另有隱情恤批,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布裹赴,位于F島的核電站喜庞,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏棋返。R本人自食惡果不足惜延都,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,940評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望睛竣。 院中可真熱鬧旷祸,春花似錦在孝、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至发框,卻和暖如春框咙,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背簿姨。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評論 1 266
  • 我被黑心中介騙來泰國打工距误, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人扁位。 一個(gè)月前我還...
    沈念sama閱讀 46,382評論 2 360
  • 正文 我出身青樓准潭,卻偏偏與公主長得像,于是被迫代替她去往敵國和親域仇。 傳聞我的和親對象是個(gè)殘疾皇子刑然,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,543評論 2 349

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

  • 函數(shù)聲明和函數(shù)表達(dá)式有什么區(qū)別 函數(shù)聲明語法:function functionName(arg0,arg1,ar...
    _Dot912閱讀 568評論 0 3
  • 1.函數(shù)聲明和函數(shù)表達(dá)式有什么區(qū)別 函數(shù)就是一段可以反復(fù)調(diào)用的代碼塊。函數(shù)還能接受輸入的參數(shù)暇务,不同的參數(shù)會返回不同...
    徐國軍_plus閱讀 472評論 0 0
  • 聲明前置和作用域也是JS 部分面試称寐樱考點(diǎn) 1.函數(shù)聲明和函數(shù)表達(dá)式有什么區(qū)別 函數(shù)聲明:使用function關(guān)鍵字...
    湖衣閱讀 196評論 0 0
  • 函數(shù)聲明和函數(shù)表達(dá)式有什么區(qū)別 JavaScript 中需要?jiǎng)?chuàng)建函數(shù)的話,有兩種方法:函數(shù)聲明垦细、函數(shù)表達(dá)式择镇,各自寫...
    蕭雪圣閱讀 949評論 2 2
  • 1.函數(shù)聲明和函數(shù)表達(dá)式有什么區(qū)別 function命令聲明的代碼區(qū)塊,就是一個(gè)函數(shù)括改。function命令后面是函...
    饑人谷_Leon閱讀 279評論 0 0