最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JS溫故而知新之變量提升和時間死區(qū)

 更新時間:2019年01月27日 08:31:02   作者:Murphywuwu  
這篇文章主要給大家介紹了關于JS溫故而知新之變量提升和時間死區(qū)的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

前言

開始執(zhí)行腳本時,執(zhí)行腳本的第一步是編譯代碼,然后再開始執(zhí)行代碼,如圖

另外,在編譯優(yōu)化方面來說,最開始時也并不是全部編譯好腳本,而是當函數執(zhí)行時,才會先編譯,再執(zhí)行腳本,如圖

  • 編譯階段:經歷了詞法分析,語法分析生成AST,以及代碼生成。并且在此階段,它只會掃描并且抽出環(huán)境中的聲明變量,聲明函數以便準備分配內存,所有的函數聲明和變量聲明都會被添加到名為Lexical Environment的JavaScript內部數據結構內的內存中。因此,它們可以在源代碼中實際聲明之前使用。但是,Javascript只會存儲函數聲明和變量聲明在內存,并不會存儲他們的值
  • 執(zhí)行階段:給變量x賦值,首先詢問內存你這有變量x嗎,如果有,則給變量x賦值,如果沒有則創(chuàng)建變量x并且給它賦值。

變量提升

如下圖,左邊灰色塊區(qū)域,是演示函數執(zhí)行前的編譯階段,先抽出所有聲明變量和聲明函數,并進行內存分配。然后再開始執(zhí)行代碼,在執(zhí)行第一行代碼的時候,若是變量a存在于內存中,則直接給變量a賦值。而執(zhí)行到第二行時,變量b并沒有在內存中,則會創(chuàng)建變量b并給它賦值。

Lexical enviroment是一種包含標識符變量映射的數據結構

LexicalEnviroment = {
 Identifier: <value>,
 Indentifier: <function object>
}

簡而言之,Lexical enviroment就是程序執(zhí)行過程中變量和函數存在的地方。

let,const變量

console.log(a)
let a = 3;

輸出

ReferenceError: a is not defined

所以let和const變量并不會被提升嗎?

這個答案會比較復雜。所有的聲明(function, var, let, const and class)在JavaScript中都會被提升,然而var聲明被undefined值初始化,但是let和const聲明的值仍然未被初始化。

它們僅僅只在Javascript引擎運行期間它們的詞法綁定被執(zhí)行在才會被初始化。這意味著引擎在源代碼中聲明它的位置計算其值之前,你無法訪問該變量。這就是我們所說的時間死區(qū),即變量創(chuàng)建和初始化之間的時間,我們無法訪問該變量。

如果JavaScript引擎仍然無法在聲明它們的行中找到let或者const的值,它將為它們分配undefined值或返回錯誤值(在const的情況下會返回錯誤值)。

6a9a50532bf60f5fac6b3c.png](evernotecid://F2BCA3B5-CC5A-4EB3-BD61-DD865800F342/appyinxiangcom/10369121/ENResource/p1163)

let a;
console.log(a); // outputs undefined
a = 5;

在編譯階段,JavaScript引擎遇到變量a并將它存儲在lexical enviroment,但是因為它是一個let變量,所以引擎不會為它初始化任何值。所以,在編譯階段,lexical enviroment看起來像下面這樣。

// 編譯階段
lexicalEnvironment = {
 a: <uninitialized>
}

現在如果我們嘗試在聲明它之前訪問該變量,JavaScript引擎將會嘗試從詞法環(huán)境中拿到這個變量的值,因為這個變量未被初始化,它將拋出一個引用錯誤。

在執(zhí)行期間,當引擎到達了變量聲明的行,它將試圖執(zhí)行它的綁定,因為該變量沒有與之關聯(lián)的值,因此它將為其賦值為unedfined

// 執(zhí)行階段
lexicalEnviroment = {
 a: undefined
}

之后,undefined將會被打印到控制臺,然后將值5賦值給變量a,lexical enviroment中變量a的值也會從undefined更新為5

functionn foo() {
console.log(a)
}

let a = 20;

foo(); 
function foo() {
console.log(a): // ReferenceError: a is not defined
}
foo();
let a = 20;

Class Declaration

就像let和const聲明一樣,class在JavaScript中也會被提升,并且和let,const一樣,知道執(zhí)行之前,它們都會保持uninitialized。因此它們同樣會受到Temporal Deal Zone(時間死區(qū))的影響。例如

let peter = new Person('Peter', 25); // ReferenceError: Person is not defined

console.log(peter);

class Person {
 constructor(name, age) {
 this.name = name;
 this.age = age;
 }
}

因此要訪問class,必須先聲明它

class Person {
 constructor(name, age) {
 this.name = name;
 this.age = age;
 }
}

let peter = new Person('Peter', 25); 
console.log(peter);
// Person { name: 'Peter', age: 25 }

所以在編譯階段,上面代碼的lexical environment(詞法環(huán)境)將如下所示:

lexicalEnvironment = {
 Person: <uninitialized>
}

當引擎執(zhí)行class聲明時,它將使用值初始化類。

lexicalEnvironment = {
 Person: <Person object>
}

提升Class Expressions

let peter = new Person('Peter', 25);
console.log(peter);
let Person = class {
 constructor(name, age) {
 this.name = name;
 this.age = age;
 }
}

let peter = new Person('Peter', 25); 
console.log(peter);
var Person = class {
 constructor(name, age) {
 this.name = name;
 this.age = age;
 }
}

所以現在我們知道在提升過程中我們的代碼并沒有被JavaScript引擎實際移動。正確理解提升機制將有助于避免因變量提升而產生的任何未來錯誤和混亂。為了避免像未定義的變量或引用錯誤一樣可能產生的副作用,請始終嘗試將變量聲明在各自作用域的頂部,并始終嘗試在聲明變量時初始化變量。

Hoisting in Modern JavaScript — let, const, and var

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。

相關文章

  • javascript刷新父頁面方法匯總詳解

    javascript刷新父頁面方法匯總詳解

    這篇文章主要介紹了javascript刷新父頁面方法匯總詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-10-10
  • js學習心得_一個簡單的動畫庫封裝tween.js

    js學習心得_一個簡單的動畫庫封裝tween.js

    下面小編就為大家?guī)硪黄猨s學習心得_一個簡單的動畫庫封裝tween.js。小編覺得挺不錯的,現在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-07-07
  • 實例分析js和C#中使用正則表達式匹配a標簽

    實例分析js和C#中使用正則表達式匹配a標簽

    本文通過2個實例,對比分析了在js和c#中使用正則表達式匹配a標簽的異同,小伙伴們自己參考下吧,有利于深刻理解正則表達式的使用。
    2014-11-11
  • JS實現保留n位小數的四舍五入問題示例

    JS實現保留n位小數的四舍五入問題示例

    這篇文章主要介紹了JS實現保留n位小數的四舍五入問題,結合完整實例形式分析了javascript針對小數四舍五入操作技巧,需要的朋友可以參考下
    2016-08-08
  • JavaScript獲取GridView中用戶點擊控件的行號,列號

    JavaScript獲取GridView中用戶點擊控件的行號,列號

    GridView中的某幾列有按鈕,需要獲取用戶當前點的按鈕的行號(捎帶的得到列號)
    2009-04-04
  • BootStrap Typeahead自動補全插件實例代碼

    BootStrap Typeahead自動補全插件實例代碼

    本文給大家介紹BootStrap Typeahead自動補全插件的實例代碼,非常不錯,具有參考借鑒價值,需要的朋友參考下
    2016-08-08
  • JS+CSS實現感應鼠標漸變顯示DIV層的方法

    JS+CSS實現感應鼠標漸變顯示DIV層的方法

    這篇文章主要介紹了JS+CSS實現感應鼠標漸變顯示DIV層的方法,涉及javascript對div層的逐漸顯示與隱藏的實現技巧,需要的朋友可以參考下
    2015-02-02
  • ES6   Promise基礎用法(resolve、reject、then、catch,all)

    ES6   Promise基礎用法(resolve、reject、then、catch,a

    Promise是JavaScript中處理異步操作的對象,它有三種狀態(tài):Pending、Fulfilled、Rejected,使用new Promise創(chuàng)建Promise對象,通過resolve和reject改變狀態(tài),then和catch方法用于處理成功和失敗的結果,本文介紹ES6 Promise用法,感興趣的朋友一起看看吧
    2024-09-09
  • js如何使用Pagination+PageHelper實現分頁

    js如何使用Pagination+PageHelper實現分頁

    本文主要介紹了js如何使用Pagination+PageHelper實現分頁,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-06-06
  • 通過js給網頁加上水印背景實例

    通過js給網頁加上水印背景實例

    這篇文章主要介紹了通過js給網頁加上水印背景實例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,,需要的朋友可以參考下
    2019-06-06

最新評論

铜鼓县| 常熟市| 田东县| 格尔木市| 晋中市| 格尔木市| 潮州市| 丰宁| 荔浦县| 洞头县| 靖边县| 衡山县| 达孜县| 嘉义市| 敖汉旗| 南汇区| 黎川县| 肇庆市| 会同县| 内黄县| 怀化市| 平邑县| 东台市| 昔阳县| 泊头市| 甘肃省| 论坛| 镇原县| 磐安县| 武清区| 石门县| 阿城市| 厦门市| 高雄县| 潜山县| 定日县| 高邮市| 阳春市| 和静县| 濮阳市| 团风县|