函數(shù)與作用域


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

  1. 函數(shù)聲明的本質(zhì)是使用function聲明一個函數(shù),而函數(shù)表達式的本質(zhì)是將一個函數(shù)賦值給一個變量弄息;
  2. 函數(shù)聲明不必放在函數(shù)調(diào)用之前猬膨,而函數(shù)表達式必須放在調(diào)用函數(shù)之前。

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

在一個作用域下褥民,所有的var聲明變量的語句在被解析時都會被前置镊讼,例如:

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

上述語句在解析時會自動將var a這條聲明語句前置誉尖,再執(zhí)行:

  console.log(a); 
  a = 3;
  console.log(a);

同理,function聲明的函數(shù)也會被前置劣领,例如:

  sayHello();
  function sayHello(){
    console.log('hello');
  }

也會將聲明語句前置耘拇,再執(zhí)行sayHello();撵颊。
這也解釋了為什么函數(shù)聲明不必放在函數(shù)調(diào)用之前。


arguments 是什么

在函數(shù)內(nèi)部惫叛,我們可以使用arguments[i]來獲取函數(shù)中相對應(yīng)的某個參數(shù)倡勇。
這樣做可以簡化函數(shù)語句,避免定義一些不必要的參數(shù)嘉涌,但會令函數(shù)的可讀性變差妻熊。


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

由于JS屬于弱類型語言,所以它不能像某些強類型語言一樣實現(xiàn)重載仑最,在JS中同名函數(shù)會進行覆蓋扔役。

要實現(xiàn)類似重載的功能,我們可以通過檢查傳入?yún)?shù)的類型和數(shù)量词身,來執(zhí)行相應(yīng)的邏輯語句厅目。


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

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

類似上述語句法严。我們將一個匿名函數(shù)用小括號括起损敷,并在末尾加一對小括號,這樣的函數(shù)在被讀取到時會立即被調(diào)用和執(zhí)行深啤。這樣的寫法相當(dāng)于將聲明函數(shù)和調(diào)用函數(shù)合并拗馒。

它的主要作用在于隔離作用域,避免污染全局變量溯街。


求n!诱桂,用遞歸來實現(xiàn)

 function factor(n){
    if(n<0){
      return'對不起,負(fù)數(shù)沒有階乘呈昔!'
    }
    if(n===0){
      return 1;
    }
    else{
      return n*factor(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 = 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

如下代碼的輸出肝劲?為什么

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

變量a的聲明會前置,但賦值不會。所以console.log(a);相當(dāng)于只聲明了變量卻沒有賦值辞槐,所以輸出undefined掷漱;
變量b既沒有聲明也沒有賦值,所以console.log(b);報錯榄檬。


如下代碼的輸出卜范?為什么

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

輸出“hello world”和報錯。
因為function sayName(name)是一個函數(shù)聲明鹿榜,它可以放在調(diào)用函數(shù)之后海雪,而不影響函數(shù)的執(zhí)行;而var sayAge = function(age)則是一個函數(shù)表達式犬缨,只有其中的var sayAge前置了喳魏,所以sayAge是一個變量而不是函數(shù),因此sayAge(10);會報錯怀薛。


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

  var x = 10
  bar() 
  function foo() {
    console.log(x)
  }
  function bar(){
    var x = 30
    foo()
  }
  //最終輸出為:10
/*
1.
globalContext = {
  AO: {
    x: 10
    foo: function
    bar: function
  },
  Scope: null
}

//聲明 foo 時 得到下面
foo.[[scope]] = globalContext.AO
//聲明 bar 時 得到下面
bar.[[scope]] = globalContext.AO

2.
barContext = {
  AO: {
    x: 30
  },
  Scope: bar.[[scope]] //globalContext.AO
}

3.
fooContext = {
  AO: {},
  Scope: foo.[[scope]] // globalContext.AO
}
*/

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

  var x = 10;
  bar() 
  function bar(){
    var x = 30;
    function foo(){
      console.log(x) 
    }
    foo();
  } 
  //最終輸出為:30
/*
1.
globalContext = {
  AO: {
    x: 10
    bar: function
  },
  Scope: null
}

//聲明 bar 時 得到下面
bar.[[scope]] = globalContext.AO

2.
barContext = {
  AO: {
    x: 30,
    foo: function
  },
  Scope: bar.[[scope]] //globalContext.AO
}
//在 bar 的執(zhí)行上下文里聲明 foo 時 得到下面
foo.[[scope]] = barContext.AO

3.
fooContext = {
  AO: {},
  Scope: foo.[[scope]] // barContext.AO
}
*/

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

  var x = 10;
  bar() 
  function bar(){
    var x = 30;
    (function (){
      console.log(x)
    })()
  }
  //最終輸出為:30
/*
1.
globalContext = {
  AO: {
    x: 10
    bar: function
  },
  Scope: null
}

//聲明 bar 時 得到下面
bar.[[scope]] = globalContext.AO

2.
barContext = {
  AO: {
    x: 30,
    function
  },
  Scope: bar.[[scope]] //globalContext.AO
}
//在 bar 的執(zhí)行上下文里聲明 function 時 得到下面
function.[[scope]] = barContext.AO

3.
functionContext = {
  AO: {},
  Scope: function.[[scope]] // barContext.AO
}
*/

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

  var a = 1;
  
  function fn(){
    console.log(a)
    var a = 5
    console.log(a)
    a++
    var a
    fn3()
    fn2()
    console.log(a)
  
    function fn2(){
      console.log(a)
      a = 20
    }
  }
  
  function fn3(){
    console.log(a)
    a = 200
  }
  
  fn()
  console.log(a)
/*
1.
globalContext = {
  AO: {
    a: 1
    fn: function
    fn3: function
  },
  Scope: null
}

fn.[[scope]] = globalContext.AO
fn3.[[scope]] = globalContext.AO

2.
fnContext = {
  AO: {
    a: undefined,
    fn2: function,
  };
  Scope: fn.[[scope]] //globalContext.AO
}

fn2.[[scope]] = fnContext.AO

3.
fn3Context = {
  AO:{
    a: 200,
  },
  Scope:fn3.[[scope]]//globalContext.AO
}
4.
fn2ConText = {
  AO:{
    a: 20,
  },
  Scope:fn2.[[scope]]//fnContext.AO
}

開始執(zhí)行代碼
-var a = 1; //聲明全局變量a = 1,即globalContext中a = 1枝恋;
-function fn() //調(diào)用函數(shù)fn()创倔;
-console.log(a) //var a聲明前置但未賦值,所以輸出undefined焚碌;
-var a = 5; //賦值a = 5畦攘,即fnContext中a = 5;
-console.log(a) //輸出5十电;
-a++ //a值自增變?yōu)?知押,即fnContext中a變?yōu)?;
-fn3 //調(diào)用函數(shù)fn3()鹃骂;
-console.log(a) //在globalContext中a = 1台盯,所以輸出1;
-a = 200 //globalContext中a值變?yōu)?00畏线;
-fn2() //調(diào)用函數(shù)fn2()静盅;
-console.log(a) //在fnContext中a = 6,所以輸出6寝殴;
-a=20 //fnContext中a值變?yōu)?0蒿叠;
-console.log(a) //在fnContext中a = 20,所以輸出20蚣常;
-console.log(a) ///globalContext中a = 200市咽,所以輸出200。

因此抵蚊,最終輸出結(jié)果為:undefined  5  1  6  20  200
*/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末魂务,一起剝皮案震驚了整個濱河市曼验,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌粘姜,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,590評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件熔酷,死亡現(xiàn)場離奇詭異孤紧,居然都是意外死亡,警方通過查閱死者的電腦和手機拒秘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評論 3 399
  • 文/潘曉璐 我一進店門号显,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人躺酒,你說我怎么就攤上這事押蚤。” “怎么了羹应?”我有些...
    開封第一講書人閱讀 169,301評論 0 362
  • 文/不壞的土叔 我叫張陵揽碘,是天一觀的道長。 經(jīng)常有香客問我园匹,道長雳刺,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,078評論 1 300
  • 正文 為了忘掉前任裸违,我火速辦了婚禮掖桦,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘供汛。我一直安慰自己枪汪,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 69,082評論 6 398
  • 文/花漫 我一把揭開白布怔昨。 她就那樣靜靜地躺著雀久,像睡著了一般。 火紅的嫁衣襯著肌膚如雪朱监。 梳的紋絲不亂的頭發(fā)上岸啡,一...
    開封第一講書人閱讀 52,682評論 1 312
  • 那天,我揣著相機與錄音赫编,去河邊找鬼巡蘸。 笑死,一個胖子當(dāng)著我的面吹牛擂送,可吹牛的內(nèi)容都是我干的悦荒。 我是一名探鬼主播,決...
    沈念sama閱讀 41,155評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼嘹吨,長吁一口氣:“原來是場噩夢啊……” “哼搬味!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,098評論 0 277
  • 序言:老撾萬榮一對情侶失蹤碰纬,失蹤者是張志新(化名)和其女友劉穎萍聊,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體悦析,經(jīng)...
    沈念sama閱讀 46,638評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡寿桨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,701評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了强戴。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片亭螟。...
    茶點故事閱讀 40,852評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖骑歹,靈堂內(nèi)的尸體忽然破棺而出预烙,到底是詐尸還是另有隱情,我是刑警寧澤道媚,帶...
    沈念sama閱讀 36,520評論 5 351
  • 正文 年R本政府宣布扁掸,位于F島的核電站,受9級特大地震影響衰琐,放射性物質(zhì)發(fā)生泄漏也糊。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,181評論 3 335
  • 文/蒙蒙 一羡宙、第九天 我趴在偏房一處隱蔽的房頂上張望狸剃。 院中可真熱鬧,春花似錦狗热、人聲如沸钞馁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽僧凰。三九已至,卻和暖如春熟丸,著一層夾襖步出監(jiān)牢的瞬間训措,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評論 1 274
  • 我被黑心中介騙來泰國打工光羞, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留绩鸣,地道東北人。 一個月前我還...
    沈念sama閱讀 49,279評論 3 379
  • 正文 我出身青樓纱兑,卻偏偏與公主長得像呀闻,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子潜慎,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,851評論 2 361

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

  • 1. 函數(shù)聲明和函數(shù)表達式有什么區(qū)別 使用function關(guān)鍵字聲明一個函數(shù)時捡多,聲明不必放到調(diào)用的前面蓖康。//函數(shù)聲...
    _李祺閱讀 277評論 0 0
  • 函數(shù)聲明和函數(shù)表達式有什么區(qū)別? 函數(shù)聲明和函數(shù)表達式是EMACScript規(guī)定的兩種不同的聲明函數(shù)的方法垒手。1.函...
    LeeoZz閱讀 350評論 0 1
  • 1.函數(shù)聲明和函數(shù)表達式有什么區(qū)別 函數(shù)聲明 代碼執(zhí)行時函數(shù)聲明會被提升到最前執(zhí)行蒜焊,所以函數(shù)的調(diào)用與函數(shù)聲明的順序...
    Feiyu_有貓病閱讀 383評論 0 0
  • 1.函數(shù)聲明和函數(shù)表達式有什么區(qū)別 函數(shù)聲明使用function關(guān)鍵字進行聲明,聲明不必放到調(diào)用的前面科贬。因為函數(shù)可...
    山門龍龍閱讀 318評論 0 0
  • 秋天越來越短山涡,像鳥兒劃過天空,稍不留神兒就將它錯過唆迁。 但此時的你我就沉浸在這秋光里,但凡美好事物之本質(zhì)應(yīng)在于其美好...
    高運達閱讀 559評論 0 1