0103函數(shù)皆串、作用域鏈淹办、聲明前置、遞歸

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

函數(shù)聲明

function name(param1, param2, ..., paramN){
   statements;
}

使用function關(guān)鍵字聲明一個(gè)函數(shù)恶复,再指定一個(gè)函數(shù)名怜森,叫函數(shù)聲明。此函數(shù)能實(shí)現(xiàn)聲明前置谤牡,函數(shù)的調(diào)用可以在任意位置副硅,即聲明前和聲明后調(diào)用均可。

函數(shù)表達(dá)式

function [name](param1, param2, ..., paramN) { 
statements;
}

函數(shù)表達(dá)式非常類似于函數(shù)聲明翅萤,并且擁有幾乎相同的語(yǔ)法恐疲。函數(shù)表達(dá)式與函數(shù)聲明的最主要區(qū)別是函數(shù)名稱,在函數(shù)表達(dá)式中可忽略它套么,從而創(chuàng)建匿名函數(shù)的方式來(lái)聲明一個(gè)函數(shù)培己。

聲明前置的是接收函數(shù)指針的變量,而不是函數(shù)本身胚泌,所以必須將聲明放在調(diào)用前面省咨。

2 . 什么是聲明前置

瀏覽器在解析JavaScript代碼時(shí),會(huì)將所有的變量聲明和函數(shù)聲明提升到它們當(dāng)前的作用域的最前面玷室。
全局作用域和函數(shù)作用域下分別實(shí)現(xiàn)各自的聲明前置零蓉。
當(dāng)發(fā)生變量和函數(shù)重名時(shí),先前置阵苇,后覆蓋壁公。

3 . 求n!,用遞歸來(lái)實(shí)現(xiàn)

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

4 . 什么是立即執(zhí)行的函數(shù)表達(dá)式绅项?有什么作用紊册?

立即執(zhí)行的函數(shù)表達(dá)式:使用某種運(yùn)算方式將函數(shù)變成一個(gè)表達(dá)式,立即得到函數(shù)的結(jié)果快耿,完成函數(shù)調(diào)用囊陡。

實(shí)現(xiàn)方式:

  • ()包裹函數(shù),得到函數(shù)表達(dá)式的一個(gè)結(jié)果---函數(shù)名掀亥,然后使用函數(shù)名調(diào)用函數(shù)撞反。因?yàn)樵趈avascript里,括號(hào)內(nèi)部不能包含語(yǔ)句搪花,當(dāng)解析器對(duì)代碼進(jìn)行解釋的時(shí)候遏片,先碰到了()嘹害,然后碰到function關(guān)鍵字就會(huì)自動(dòng)將()里面的代碼識(shí)別為函數(shù)表達(dá)式而不是函數(shù)聲明
(function(){
     var a = 1;
})();

或則

(function(){
     var a = 1;
}());
  • 使用[]或則或則&&運(yùn)算符
// 在數(shù)組初始化器內(nèi)只能是表達(dá)式
[function fn2() {}]; 
// 逗號(hào)也只能操作表達(dá)式
1, function fn3() {};
//` && `兩邊也是表達(dá)式
true && function () { /* code */ } ();
  • 使用一元運(yùn)算符得到立即執(zhí)行函數(shù)表達(dá)式
!function () { /* code */ } ();
~function () { /* code */ } ();
-function () { /* code */ } ();
+function () { /* code */ } ();

作用:利用函數(shù)作用域下吮便,變量用完即釋放的功能笔呀,來(lái)實(shí)現(xiàn)隔離作用域,污染防止全局變量的效果髓需。

5 . 如下代碼輸出什么? 寫(xiě)出作用域鏈查找過(guò)程偽代碼

var x = 10;
bar();
function foo() { 
console.log(x);
}
function bar(){
 var x = 30;
 foo(); // 輸出什么
}

foo(); // 輸出10
作用域鏈查找過(guò)程偽代碼:

globalContext = {
  AO:{
    x: 10,
    foo: function,
    bar: function,
  },
  Scope: null,
}
//在當(dāng)前的執(zhí)行上下文內(nèi)聲明的函數(shù)许师,這個(gè)函數(shù)的[[scope]]就是當(dāng)前執(zhí)行上下文
//調(diào)用函數(shù)的時(shí)候進(jìn)入到函數(shù)的執(zhí)行上下文
fooContext.Scope = globalContext;
barContext.Scope = globalContext;

fooContext = {
  AO:{
  },
  Scope: globalContext,
}

barContext = {
  AO:{
    x: 30,
  },
  Scope: globalContext,
}

6 . 如下代碼輸出什么? 寫(xiě)出作用域鏈查找過(guò)程偽代碼

var x = 10;
bar() // 輸出什么
function bar(){ 
  var x = 30;
  function foo(){
    console.log(x) 
  } 
  foo();
}

bar() // 輸出30
作用域鏈查找過(guò)程偽代碼:

globalContext = {
  AO:{
    x: 10,
    bar: function,
  },
  Scope: null,
}
barContext.Scope = globalContext;

barContext = {
  AO:{
    x: 30,
    foo: function,
  },
  Scope: globalContext,
}
fooContext.Scope = barContext;

fooContext = {
  AO:{
  },
  Scope: barContext,
}

7 . 一下代碼輸出什么? 寫(xiě)出作用域鏈的查找過(guò)程偽代碼

var x = 10;
bar() // 輸出什么
function bar(){
  var x = 30; 
  (function (){ console.log(x) })();
}

bar() // 輸出30
作用域鏈查找過(guò)程偽代碼:

globalContext = {
  AO:{
    x: 10,
    bar: function,
  },
  Scope: null,
}
barContext.Scope = globalContext;

barContext = {
  AO:{
    x: 30,
    (function(){}): funtion,
  },
  Scope: globalContext,
}
(function(){}).Scope = barContext;

(function(){})Context = {
  AO:{
  },
  Scope: barContext,
}

8.以下代碼輸出什么? 寫(xiě)出作用域鏈查找過(guò)程偽代碼

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

輸出:undefined 5 1 6 20 200
作用域鏈查找過(guò)程偽代碼:

1.
globalContext = {
  AO:{
    a: 1,
    fn: function,
    fn3: function,
  },
  Scope: null,
}
fnContext.Scope = globalContext;
fn3Context.Scope = globalContext;

fnContext = {
  AO:{
    a: undefined,//fn第一個(gè)console.log(a)
    fn2: funtion,
  },
  Scope: globalContext.AO,
}
fn2Context.Scope = fnContext;

fn2Context = {
  AO:{
  },
  Scope: fnContext,
}

fn3Context = {
  AO:{
  },
  Scope: globalContext,
}

2. 
fnContext = {
  AO:{
    a: 5,//fn第二個(gè)console.log(a)
    fn2: funtion,
  },
  Scope: globalContext,
}

3. 
globalContext = {
  AO:{
    a: 1,//fn3的console.log(a)
    fn: function,
    fn3: function,
  },
  Scope: null,
}
fnContext = {
  AO:{
    a: 6,//a++之后
    fn2: funtion,
  },
  Scope: globalContext,
}

fn3Context = {
  AO:{
  },
  Scope: globalContext,
}

4.
globalContext = {
  AO:{
    a: 200,//fn3的a = 200
    fn: function,
    fn3: function,
  },
  Scope: null,
}
fnContext = {
  AO:{
    a: 6,//fn2的console.log(a)
    fn2: funtion,
  },
  Scope: globalContext,
}

fn2Context = {
  AO:{
  },
  Scope: fnContext,
}

fn3Context = {
  AO:{
  },
  Scope: globalContext,
}

5.
fnContext = {
  AO:{
    a: 20,//fn2里a = 20;fn的第三個(gè)console.log(a)
    fn2: funtion,
  },
  Scope: globalContext,
}

6.
globalContext = {
  AO:{
    a: 200,//全局最后的console.log(a)
    fn: function,
    fn3: function,
  },
  Scope: null,
}

9.以下代碼輸出什么僚匆?畫(huà)出執(zhí)行過(guò)程作用域偽代碼(難度五顆星微渠,用興趣的同學(xué)可選做)

function fn(){ 
  var x = 1; 
  function fn2(){
    x++;
   console.log(x) ; 
  } 
  return fn2;
}
var foo = fn();
var bar = fn();
foo();
bar();
foo();

輸出:2 2 3
作用域鏈查找過(guò)程偽代碼:

globalContext = {
  AO:{
    fn: function,
    foo: function,//fn2
    bar: function,//fn2
  },
  Scope: null,
}
fnContext.Scope = globalContext;
fooContext.Scope = globalContext;
barContext.Scope = globalContext;

fnContext = {
  AO: {
    x: 1,
    fn2: function,
  }
  Scope: globalContext;
}
fn2Context.Scope = fnContext;

fn2Context = {
  AO: {
  }
  Scope: fnContext;
}

//首先,foo和bar是兩個(gè)不同的變量咧擂,占用不同的內(nèi)存資源逞盆,是兩個(gè)獨(dú)立的實(shí)例,互不影響屋确。

1.foo();

fooContext = {
  AO: {
  }
 //foo的Scope具有g(shù)lobalContext和fnContext雙重屬性
  Scope: fnContext, 
         globalContext,
}

fnContext = {
  AO: {
    x: 2,//x++后
    fn2: function,
  }
  Scope: globalContext;
}

2.bar();

barContext = {
  AO: {
  }
  //bar的Scope具有g(shù)lobalContext和fnContext雙重屬性纳击,且和foo的Scope互不影響
  Scope: fnContext, 
         globalContext,
}

fnContext = {
  AO: {
    x: 2,//x++后
    fn2: function,
  }
  Scope: globalContext,
}

3.foo();

fooContext = {
  AO: {
  }
  //foo的Scope具有g(shù)lobalContext和fnContext雙重屬性
  Scope: fnContext, 
         globalContext,
}

fnContext = {
  AO: {
    x: 3,//x++后
    fn2: function,
  }
  Scope: globalContext,
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市攻臀,隨后出現(xiàn)的幾起案子焕数,更是在濱河造成了極大的恐慌,老刑警劉巖刨啸,帶你破解...
    沈念sama閱讀 218,525評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件堡赔,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡设联,警方通過(guò)查閱死者的電腦和手機(jī)善已,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)离例,“玉大人换团,你說(shuō)我怎么就攤上這事」” “怎么了艘包?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,862評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)耀盗。 經(jīng)常有香客問(wèn)我想虎,道長(zhǎng),這世上最難降的妖魔是什么叛拷? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,728評(píng)論 1 294
  • 正文 為了忘掉前任舌厨,我火速辦了婚禮,結(jié)果婚禮上忿薇,老公的妹妹穿的比我還像新娘裙椭。我一直安慰自己躏哩,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,743評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布揉燃。 她就那樣靜靜地躺著震庭,像睡著了一般。 火紅的嫁衣襯著肌膚如雪你雌。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,590評(píng)論 1 305
  • 那天二汛,我揣著相機(jī)與錄音婿崭,去河邊找鬼。 笑死肴颊,一個(gè)胖子當(dāng)著我的面吹牛氓栈,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播婿着,決...
    沈念sama閱讀 40,330評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼授瘦,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了竟宋?” 一聲冷哼從身側(cè)響起提完,我...
    開(kāi)封第一講書(shū)人閱讀 39,244評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎丘侠,沒(méi)想到半個(gè)月后徒欣,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,693評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蜗字,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,885評(píng)論 3 336
  • 正文 我和宋清朗相戀三年打肝,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片挪捕。...
    茶點(diǎn)故事閱讀 40,001評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡粗梭,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出级零,到底是詐尸還是另有隱情断医,我是刑警寧澤,帶...
    沈念sama閱讀 35,723評(píng)論 5 346
  • 正文 年R本政府宣布妄讯,位于F島的核電站孩锡,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏亥贸。R本人自食惡果不足惜躬窜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,343評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望炕置。 院中可真熱鬧荣挨,春花似錦男韧、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,919評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至口锭,卻和暖如春朦前,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背鹃操。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,042評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工韭寸, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人荆隘。 一個(gè)月前我還...
    沈念sama閱讀 48,191評(píng)論 3 370
  • 正文 我出身青樓恩伺,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親椰拒。 傳聞我的和親對(duì)象是個(gè)殘疾皇子晶渠,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,955評(píng)論 2 355

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