JS函數作用域鏈

1.函數聲明和函數表達式

函數聲明和函數表達式都可以聲明函數,但使用函數聲明的方法,聲明不必放在調用前;使用函數表達式,聲明需要在調用前,可以省略函數名。
例:

 function sayHello(){
    console.log('hello')
  } 
//函數聲明

var sayHello = function(){
    console.log('hello');
  }
//函數表達式

2.變量與函數的聲明前置

在一個作用域下,var聲明的變量和function聲明的函數會前置,聲明的語句會優先執行。

3.arguments 對象

Arguments是個類似數組但不是數組的對象,說他類似數組是因為其具備數組相同的訪問性質及方式,能夠由arguments[n]來訪問對應的單個參數的值,并擁有數組長度屬性length。還有就是arguments對象存儲的是實際 傳遞給函數的參數,而不局限于函數聲明所定義的參數列表,而且不能顯式創建 arguments 對象。

4.函數的"重載"怎樣實現

JavaScript不支持函數的重載,即不能夠定義同樣的函數然后通過編譯器去根據不同的參數執行不同的函數。但可以在函數內部定義多種模式,根據傳進來的參數信息進行匹配。

5.立即執行函數表達式

立即執行函數表達式是一種可以使函數在被定義后立即執行的一種寫法,在javascript里,括號內部不能包含語句,當解析器對代碼進行解釋的時候,先碰到了(),然后碰到function關鍵字就會自動將()里面的代碼識別為函數表達式而不是函數聲明。例如下面的代碼:

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

立即執行函數表達式的作用:一是不必為函數命名,避免了污染全局變量;二是IIFE內部形成了一個單獨的作用域,可以封裝一些外部無法讀取的私有變量。避免了污染全局變量。

6.求n!,用遞歸來實現

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

var result=factor(5);
console.log(result)

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 undefined ["小谷", 3] name vally
getInfo('男');  //結果: name:男 undefined undefined ["男"] name vally

8. 寫一個函數,返回平方和

   function sumOfSquares(){
         var sum=0;
         for(var i=0;i<arguments.length;i++){
               sum=sun+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,因為變量a聲明提前,但此時還未被賦值
    var a = 1;
    console.log(b); //報錯“b is not defined”,因為b未被聲明

10. 如下代碼的輸出?

    sayName('world');
    sayAge(10);
    function sayName(name){
        console.log('hello ', name); //輸出hello world,因為函數聲明提前
    }
    var sayAge = function(age){
        console.log(age); //報錯,因為使用函數表達式必須在其后調用,否則認為sayAge不是函數
    };

11. 作用域鏈查找過程偽代碼 ,舉例如下:

var x = 10
bar() 
function foo() {
  console.log(x)
}
function bar(){
  var x = 30
  foo()
}
/*****************************************************************************/
//作用域鏈查找過程如下:
//首先全局作用域中聲明的變量有:x,函數有foo(),bar()
globalContext = {
    AO:{
        x:10
        foo:function
        bar:function
    },
    Scope:null
}
//此時被聲明的函數foo(),bar()的scope為 globalContext.AO
foo.[[scope]] = globalContext.AO
bar.[[scope]] = globalContext.AO
//繼續執行,進入bar的執行上下文
barContext = {
    AO:{
     x:30
    }
    scope:bar.[[scope]] = globalContext.AO
}
//調用foo從scope中找到,進入foo的執行上下文
fooContext = {
    AO:{    
    }
    scope:foo.[[scope]] = globalContext.AO
}
//從foo的scope:globalContext.AO中找到x:10,所以輸出10。

輸出10

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

var x = 10;
bar() 
function bar(){
  var x = 30;
  function foo(){
    console.log(x) 
  }
  foo();
}
/***********************************************************************/
//全局作用域中聲明變量x,函數bar()
globalContext = {
  AO: {
    x: 10
    bar: function
  }
  Scope: null
}
//此時被聲明的bar()的scope為globalContext.AO
bar.[[scope]] = globalContext.AO
//進入bar執行上下文
barContext = {
  AO: {
    x: 30
    foo: function
  }
  Scope: bar.[[scope]] = globalContext.AO
}
//foo()被聲明,它的scope為barContext.AO
foo.[[scope]] = barContext.AO

fooContext = {
  AO: {  }
  Scope: foo.[[scope]] = barContext.AO
}

輸出為30

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

var x = 10;
bar() 
function bar(){
  var x = 30;
  (function (){
    console.log(x)
  })()
}
/************************************************************************************************/
//全局作用域聲明變量x,函數bar()
globalContext = {
  AO: {
    x: 10
    bar: function
  }
  Scope: null
}
bar.[[scope]] = globalContext.AO

barContext = {
  AO: {
    x: 30
    anonymous:function //匿名函數anonymous
  }
  Scope: bar.[[scope]] = globalContext.AO
}
anonymous.[[scope]] = barContext.AO

anonymousContext = {
  AO: { }
  Scope: anonymous.[[scope]] = barContext.AO
} 

輸出為30

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

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)
/************************************************************************************************/
globalContext = {
  AO: {
    a: 1
    fn: function
    fn3: function
  }
  Scope: null
}
fn.[[scope]] = globalContext.AO
fn3.[[scope]] = globalContext.AO

fnContext = {
  AO: {
    a: undefined
    fn2: function
  }
  Scope: fn.[[scope]] = globalContext.AO
}
fn2.[[scope]] = fnContext.AO
//進入fn后先輸出undefined,a賦值為5后輸出5
fn3Context = {
  AO: {}
  Scope: fn3.[[scope]] = globalContext.AO
}
 //輸出:1
fn2Context = {
  AO: {}
  Scope: fn2.[[scope]] = fnContext.AO
}
console.log(a) //輸出200

最后結果為:undefined 5 1 6 200

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,908評論 6 541
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,324評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,018評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,675評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,417評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,783評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,779評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,960評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,522評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,267評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,471評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,009評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,698評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,099評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,386評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,204評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,436評論 2 378

推薦閱讀更多精彩內容

  • 第5章 引用類型(返回首頁) 本章內容 使用對象 創建并操作數組 理解基本的JavaScript類型 使用基本類型...
    大學一百閱讀 3,263評論 0 4
  • 繼承 一、混入式繼承 二、原型繼承 利用原型中的成員可以被和其相關的對象共享這一特性,可以實現繼承,這種實現繼承的...
    magic_pill閱讀 1,074評論 0 3
  • 作用域鏈:JavaScript需要查詢一個變量x時,首先會查找作用域鏈的第一個對象,如果以第一個對象沒有定義x變量...
    風___________閱讀 272評論 0 0
  • 昨晚經不住老公一再申請,家里今年第一次開了空調,睡覺時,就覺腳底呼呼過風,把毛巾被裹在腳上,才得一夜安睡。 上午幾...
    misang閱讀 189評論 1 4
  • 在這給大家分享一下我的大學生活,有點空虛有點冷,但是我在慢慢改變自己,也希望能在畢業之前活出一個像樣的自己,也能過...
    ShaulQiao閱讀 406評論 0 2