国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

【6】JavaScript 函數高級——執行上下文與執行上下文棧、變量提升(圖解+典型實例分析)

niuxiaowei111 / 2945人閱讀

摘要:函數和變量相比,會被優先提升。這意味著函數會被提升到更靠前的位置。僅提升聲明,而不提升初始化。

JavaScript 函數高級——執行上下文與執行上下文棧(圖解+典型實例分析) 變量提升與函數提升

變量聲明提升

通過 var 定義(聲明)的變量,在定義語句之前就可以訪問到

值:undefined

/*
  面試題 : 輸出 undefined
   */
var a = 3
function fn() {
    console.log(a) // undefined  調用fn()后進入函數體內部,通過 var 聲明的變量提升,值為undefined
    var a = 4
    console.log(a) // 4
}
fn()
console.log("----")
可以用開發工具的代碼調試工具設置斷點,清楚地看到a的值的變化。

函數聲明提升

通過 function 聲明的函數,在該函數聲明之前就可以直接調用

值:函數定義(對象)

console.log(b) // undefined  通過 var 聲明的變量b         變量聲明提升
fn2() // fn2()               通過 function 聲明的函數fn2  函數聲明提升
fn3() // 報錯                 通過 var 聲明的函數fn3       變量聲明提升

var b = 3
function fn2() {
  console.log("fn2()")
}

var fn3 = function () {
  console.log("fn3()")
}

!!注意 var a = 3var fn = function(){ }只要是var聲明的,都是變量聲明提升,值都是undefined

??!注意:var fn = function(){ }屬于變量聲明提升,不是函數聲明提升

問題:變量提升和函數提升是如何產生的?

這是因為在JavaScript中執行上下文的工作方式造成的。
函數和變量相比,會被優先提升。這意味著函數會被提升到更靠前的位置。
JavaScript 僅提升聲明,而不提升初始化。

執行上下文
執行上下文個數 = n(調用的函數個數) + 1(全局執行上下文)
// 變量聲明提升,函數聲明提升,全局代碼的函數和方法添加為Window的方法和屬性
console.log(a1, window.a1) // undefined   undefined
window.a2() // a2()
console.log(this) // Window

var a1 = 3
function a2() {
    console.log("a2()")
}
console.log(a1) // 3
代碼分類(位置)

全局代碼

函數代碼

全局執行上下文

執行全局代碼前window確定為全局執行上下文

全局數據進行預處理:

var 定義的全局變量==>undefined,添加為window屬性

function 聲明的全局函數==>賦值(fun),添加為window的方法

this==>賦值(window)

開始執行全局代碼

函數執行上下文

調用函數,準備執行函數體之前,創建對應的函數執行上下文對象

局部數據進行預處理

形參變量==>賦值(實參)==>添加為執行上下文的屬性

arguments==>賦值(實參列表),添加為執行上下文的屬性

var 定義的局部變量==>undefined==>添加為執行上下文的屬性

function聲明的函數==>賦值(fun)==>添加為執行上下文的屬性

this==>賦值(調用函數的對象)

開始執行函數體代碼

執行上下文棧 理解

在全局代碼執行前, JS引擎就會創建一個來存儲管理所有的執行上下文對象

全局執行上下文(window)確定后, 將其添加到棧中(壓棧)

函數執行上下文創建后, 將其添加到棧中(壓棧)

在當前函數執行完后,將棧頂的對象移除(出棧)

當所有的代碼執行完后, 棧中只剩下window

流程分析
// 1. 進入全局上下文
var a = 10
var bar = function (x) {
    var b = 5
    // 3. 進入foo執行上下文
    foo(x + b)
}
var foo = function (y) {
    var c = 5
    console.log(a + c + y)
}
// 2. 進入bar函數執行上下文
bar(10)  // 30

用斷點調試工具查看執行上下文調用棧

面試題 題1:遞歸調用的執行上下文
console.log("gb: " + i)  
var i = 1
foo(1)
function foo(i) {
    if (i == 4) {
        return
    }
    console.log("fb:" + i)
    foo(i + 1) //遞歸調用: 在函數內部調用自己
    console.log("fe:" + i)
}
console.log("ge: " + i) // ge:1

依次輸出什么?

整個過程中產生了幾個執行上下文?

5個 = 4個函數執行上下文 + 1個全局執行上下文

調試查看:

題2:函數提升優先于變量提升,且不會被變量聲明覆蓋,但是會被變量賦值覆蓋。
console.log(foo)  // ? foo() {console.log("函數聲明")}
console.log(foo()) // 我是一個函數  undefined
function foo() {
  console.log("我是一個函數")
}
var foo = 3
console.log(foo) // 3
console.log(foo()) // foo is not a function

相當于

function foo(){
    console.log("函數聲明")
}  // 函數聲明先提升
var foo   // 變量聲明提升,變量初始化未提升,此時foo的值為undefined,所以不會覆蓋函數聲明
console.log(foo)  // 打印出? foo() {console.log("函數聲明")}
console.log(foo()) // 我是一個函數  undefined
foo = 3 // 此時給foo賦值為3,則會覆蓋前面的
console.log(foo) // 3
console.log(foo()) // foo is not a function,因為此時foo=3
題3:考察全局環境下的變量提升
if (!(t in window)) {
    var t = 1
}
console.log(t)  // undefined
t in window
// true

原因就在于變量t被提升到了全局環境最頂部,通過關鍵字var在全局作用域中聲明的變量將作為全局對象(window)的一個屬性,上面的代碼JavaScript其實是這樣解析的:

var t
if (!(t in window)) {
    var t = 1
}
console.log(t) // undefined
題4(好題)
var c = 1
function c(c) {
  console.log(c)
  var c = 3
}
c(2) // 報錯  c is not a function 

注意:函數提升為c(),整個函數提升,所以上面的代碼相當于下面這樣,這樣就很清楚了吧!

function c(c) {
    console.log(c)
    var c = 3
}
var c

c = 1
c(2) //所以 c is not a function

函數體內的代碼根本就沒機會執行。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/104157.html

相關文章

  • javascript高級程序設計》筆記:內存執行環境

    摘要:因此,所有在方法中定義的變量都是放在棧內存中的當我們在程序中創建一個對象時,這個對象將被保存到運行時數據區中,以便反復利用因為對象的創建成本通常較大,這個運行時數據區就是堆內存。 上一篇:《javascript高級程序設計》筆記:繼承近幾篇博客都會圍繞著圖中的知識點展開 showImg(https://segmentfault.com/img/bVY0C4?w=1330&h=618);...

    fuyi501 評論0 收藏0
  • 【進階1-2期】JavaScript深入之執行下文變量對象

    摘要:本計劃一共期,每期重點攻克一個面試重難點,如果你還不了解本進階計劃,點擊查看前端進階的破冰之旅本期推薦文章深入之執行上下文棧和深入之變量對象,由于微信不能訪問外鏈,點擊閱讀原文就可以啦。 (關注福利,關注本公眾號回復[資料]領取優質前端視頻,包括Vue、React、Node源碼和實戰、面試指導) 本周正式開始前端進階的第一期,本周的主題是調用堆棧,今天是第二天。 本計劃一共28期,每期...

    Richard_Gao 評論0 收藏0
  • 【進階1-1期】理解JavaScript 中的執行下文執行

    摘要:首次運行代碼時,會創建一個全局執行上下文并到當前的執行棧中。執行上下文的創建執行上下文分兩個階段創建創建階段執行階段創建階段確定的值,也被稱為。 (關注福利,關注本公眾號回復[資料]領取優質前端視頻,包括Vue、React、Node源碼和實戰、面試指導) 本周正式開始前端進階的第一期,本周的主題是調用堆棧,,今天是第一天 本計劃一共28期,每期重點攻克一個面試重難點,如果你還不了解本進...

    import. 評論0 收藏0
  • 【進階1-3期】JavaScript深入之內存空間詳細圖解

    摘要:進階期理解中的執行上下文和執行棧進階期深入之執行上下文棧和變量對象但是今天補充一個知識點某些情況下,調用堆棧中函數調用的數量超出了調用堆棧的實際大小,瀏覽器會拋出一個錯誤終止運行。 (關注福利,關注本公眾號回復[資料]領取優質前端視頻,包括Vue、React、Node源碼和實戰、面試指導) 本周正式開始前端進階的第一期,本周的主題是調用堆棧,今天是第3天。 本計劃一共28期,每期重點攻...

    coordinate35 評論0 收藏0
  • 【進階2-2期】JavaScript深入之從作用域鏈理解閉包

    摘要:使用上一篇文章的例子來說明下自由變量進階期深入淺出圖解作用域鏈和閉包訪問外部的今天是今天是其中既不是參數,也不是局部變量,所以是自由變量。 (關注福利,關注本公眾號回復[資料]領取優質前端視頻,包括Vue、React、Node源碼和實戰、面試指導) 本周正式開始前端進階的第二期,本周的主題是作用域閉包,今天是第7天。 本計劃一共28期,每期重點攻克一個面試重難點,如果你還不了解本進階計...

    simpleapples 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<