成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

JavaScript抽象概念簡而不單,單而不簡!

開發(fā) 前端
想必大伙兒看到本期的標題很有疑惑,為什么是簡而不單,單而不簡的執(zhí)行上下文呢?我來先解釋一下,對于 javaScript 上一些抽象的概念,我們可以把它講的非常復雜,也可以把它講的極其簡單,更可以把它講的既復雜又簡單。

[[384723]]

本文轉載自微信公眾號「小鹿動畫學編程」,作者小鹿   。轉載本文請聯(lián)系小鹿動畫學編程公眾號。

想必大伙兒看到本期的標題很有疑惑,為什么是簡而不單,單而不簡的執(zhí)行上下文呢?我來先解釋一下,對于 javaScript 上一些抽象的概念,我們可以把它講的非常復雜,也可以把它講的極其簡單,更可以把它講的既復雜又簡單。

嗯~ 最近重新回顧了這些抽象的概念,發(fā)現(xiàn)有些概念之前并不能很好的融會貫通,所以把這些相對抽象難以理解的概念作為幾期文章來寫。

我個人覺得要想更好的理解抽象概念,不得不借助可視化的圖像減少作者和讀者之間的理解力和理解差錯。所以,不用擔心,這篇文章小鹿會通過加入更多的圖片深入淺出的解釋這些抽象的概念。

1、執(zhí)行上下文

1.1 JavaScript 引擎

說到執(zhí)行上下文,不得不先扯扯 JavaScript 引擎,JavaScript 引擎是什么?考慮到這篇文章不專門寫 JavaScript 引擎,可以自己谷歌一下。說白了,JavaScript 引擎就是用來「解釋」、「編譯」和「執(zhí)行」JavaScript 代碼的。

畢竟開發(fā)人員寫的 JS 代碼只能夠讓開發(fā)者認得出來,交給計算機,由于計算機只識別二進制,所以中間需要進行一系列的解釋和轉化才能看懂執(zhí)行這些 JavaScript 代碼。

1.2 執(zhí)行棧 (Execution stack)

小鹿注:保證 JavaScript 代碼的執(zhí)行"順序"。

JavaScript 引擎既然可以執(zhí)行 JS 的代碼,那么是按照什么順序執(zhí)行的,又是怎么保證這些順序而不被所打亂的。先看一段簡單的代碼:

  1. var foo2 = function () { 
  2.   console.log('foo2'); 
  3.  
  4. var foo1 = function () { 
  5.   console.log('foo1'); 
  6.   foo2() 
  7.   console.log('foo3'
  8.  
  9. foo1(); // 輸出:“foo1  foo2  foo3” 

通過上述代碼片段的執(zhí)行,輸出的順序為'foo1 foo2 foo3'。

代碼執(zhí)行,foo1()函數(shù)先執(zhí)行,首先輸出'foo1',遇到 foo2() 函數(shù)的執(zhí)行命令,將執(zhí)行權交給 foo2, foo2 函數(shù)體執(zhí)行,輸出'foo2'。foo2 執(zhí)行完畢后,將執(zhí)行權交回 foo1 函數(shù),最后輸出'foo3'

我們可以找出上述代碼執(zhí)行的規(guī)律,先執(zhí)行的函數(shù),會在最后退出,后執(zhí)行的函數(shù),先執(zhí)行完畢。這個執(zhí)行順序不就是“棧”的“先進后出”``“后進先出”的結構嘛。JavaScript 引擎將其這種執(zhí)行結構稱為「執(zhí)行棧」,用于保證 JavaScript 代碼的順序。

1.3 執(zhí)行上下文(Exception Context)

小鹿注:將執(zhí)行的代碼"模塊化" —— 執(zhí)行上下文的分類。

什么是執(zhí)行上下文?雖然我們在“執(zhí)行上下文”詞義上很難直接理解,但是它具體代表的是什么,是很容易理解的,下面我把“執(zhí)行上下文”的抽象概念進行具體化。

上述我們已經(jīng)解釋了 JavaScript 引擎是使用執(zhí)行棧來保證代碼的執(zhí)行順序的,但是執(zhí)行過程中需要涉及到一些變量的作用范圍界定(作用域)、閉包等復雜情況,我們需要 JavaScript 引擎引入一種機制來解決這些看起來復雜的問題,所以「執(zhí)行上下文」的概念產生了。

但是,執(zhí)行上下文是什么?這不得不讓我想起組件的模塊化開發(fā),之前的一個網(wǎng)頁應用代碼從上到下一個文件寫下來幾千行代碼,難以閱讀、難以維護,所以有了后來的模塊化開發(fā)。每個模塊都有自己的功能,都有屬于自己的局部變量和樣式。

我們可以理解為 JavaScript 引擎為了更好的解釋和執(zhí)行代碼,所以引入類似于像組件模塊的“執(zhí)行上下文”的概念用于管理運行時代碼的復雜度。

2、執(zhí)行上下文的分類

上述我們把抽象的“執(zhí)行上下文”類似于“模塊”的具體概念便于理解。當然,執(zhí)行上下文也就是所謂的“模塊”也有不同的分類,在這里具體只展開兩種,「全局執(zhí)行上下文」和「局部執(zhí)行上下文」。

2.1 全局執(zhí)行上下文(Global Exception Context)

全局上下文這個“模塊”由兩部分組成,「全局對象」和「this」。

下圖是全局執(zhí)行上下文的最基本形式。包含一個 window 對象,以及一個 this 變量,而這個 this 變量是指向 window 對象的,如最右圖的打印結果。

從這里我們看出,執(zhí)行上下文可以理解為是一個在內存中的「對象和變量」集合的模塊(或者說是片段),這也是為什么我們可以把它看作類似“模塊”的原因(除此之外還有其他作用)

小鹿注:為了便于理解,定義是我自己總結的,如有欠缺歡迎指出~

2.2 局部執(zhí)行上下文

局部執(zhí)行上下文和全局執(zhí)行上下文類似,但不完全相同,在函數(shù)局部執(zhí)行上下文中,需要注意的有以下兩點:

  • 函數(shù)傳入的參數(shù)會作為局部執(zhí)行上下文的變量來存儲
  • 局部上下文有一個 arguments 參數(shù)對象(參考)局部執(zhí)行上下文內容會在下面的兩個階段中詳細講到。

3、執(zhí)行上下文兩個階段

無論是全局執(zhí)行上下文還是局部的執(zhí)行上下文,都會經(jīng)歷兩個階段,分別是「創(chuàng)建」和「執(zhí)行」。

如下我們有一段代碼:

  1. var name = "小鹿"
  2. var age = 23; 
  3.  
  4. function getInfo(){ 
  5.   return { 
  6.     namename
  7.     age: age 
  8.   }; 

3.1 創(chuàng)建階段(Creation)

創(chuàng)建階段要完成的事情,如下:

  • 在堆內存中創(chuàng)建全局對象(global object)—— 瀏覽器環(huán)境是 windows,Node 環(huán)境是 Global
  • 讓 this 變量指向這個全局對象
  • 設置當前執(zhí)行上下文中「變量和函數(shù)」的內存空間
  • 將聲明的變量加入內存中(同時掛在到全局對象上),為變量賦值 undifined,函數(shù)存儲的是字符串形式

小鹿注:左 (1) 圖執(zhí)行的代碼,左 (2) 圖創(chuàng)建階段完成后的執(zhí)行上下文內存中狀態(tài),右 (1) 創(chuàng)建階段全局對象的狀態(tài)。

JavaScript 引擎在執(zhí)行代碼之前,先在堆內存中創(chuàng)建全局執(zhí)行上下文,生成全局對象(global object),然后讓 this 變量指向這個變量。JavaScript 發(fā)現(xiàn)代碼中聲明的兩個變量 name 和 age,然后在全局執(zhí)行上下文中申請內存空間,將變量存儲到該內存空間內,然后為該變量賦值 undefined,函數(shù)就以字符串的形式存儲在內存中。

小鹿注:在創(chuàng)建階段為變量聲明指定默認值(undefined)的過程稱為「變量提升」。

3.2 執(zhí)行階段(Execution)

全局執(zhí)行上下文創(chuàng)建完成之后,開始由創(chuàng)建狀態(tài)(Creation)變?yōu)閳?zhí)行狀態(tài)( Execution)。JavaScript 引擎開始逐行運行和執(zhí)行代碼,并為在創(chuàng)建階段放入內存的變量賦予值。

小鹿注:左 (1) 圖執(zhí)行的代碼,左 (2) 圖執(zhí)行階段完成后的執(zhí)行上下文內存中狀態(tài),右 (1) 執(zhí)行階段全局對象的狀態(tài)。

局部執(zhí)行上下文和全局執(zhí)行上下文的創(chuàng)建和執(zhí)行過程是一模一樣的。但是全局執(zhí)行上下文創(chuàng)建一次,而函數(shù)局部執(zhí)行上下文是隨著函數(shù)的每次調用都要創(chuàng)建一個局部執(zhí)行上下文。

還是上述例子,執(zhí)行結果如下:

  1. var name = "小鹿"
  2. var age = 23; 
  3.  
  4. function getInfo(name){ 
  5.   console.log(name); 
  6.   return { 
  7.     namename
  8.     age: age 
  9.   }; 
  10.  
  11. getInfo(name); 

函數(shù)局部上下文執(zhí)行狀態(tài)如下:

小鹿注:由于函數(shù)中沒有定義新的變量,所以在這里沒有變量提升。

我們了解了什么是函數(shù)局部上下文,當函數(shù)局部上下文執(zhí)行完畢之后,就會執(zhí)行出棧操作,將執(zhí)行權交給父級執(zhí)行上下文(可能是局部執(zhí)行上下文,也可能是全局執(zhí)行上下文),上述 getInfo 函數(shù)執(zhí)行完畢的狀態(tài)如下圖所示。

此時的函數(shù)執(zhí)行完畢,局部執(zhí)行上下文出棧銷毀,執(zhí)行權交給全局執(zhí)行上下文繼續(xù)執(zhí)行其他代碼。

由于 JavaScript 是單線程的,一次只能執(zhí)行一個任務,為了方便大伙兒理解,左(3)圖 是執(zhí)行棧的調用情況。當然,我們也可以發(fā)現(xiàn),左(2)圖是以嵌套的方式來模擬執(zhí)行棧的操作,每一個嵌套選項都是堆棧中一個新的執(zhí)行上下文。

4、小結

執(zhí)行上下文在 JavaScript 中是一個非常重要的概念,在接下幾期的進階文章中,作用域、作用域、閉包、this等概念,都會與本期文章內容掛鉤。

責任編輯:武曉燕 來源: 小鹿動畫學編程
相關推薦

2014-03-06 11:29:39

銳捷網(wǎng)絡簡網(wǎng)絡

2009-07-02 19:03:34

虛擬化服務器虛擬化VMware

2016-03-11 10:06:27

CIO時代網(wǎng)

2013-03-21 17:42:35

2022-03-27 20:37:42

系統(tǒng)抽象語言

2011-07-28 09:50:58

設計模式

2010-06-25 14:39:12

多協(xié)議標簽交換

2013-01-15 09:14:20

2014-10-22 15:49:08

2010-07-23 08:22:00

動態(tài)語言框架

2015-04-27 09:01:07

銳捷網(wǎng)絡銳捷智分

2015-05-27 09:31:27

銳捷

2015-06-05 09:39:05

銳捷

2014-03-18 09:46:35

銳捷網(wǎng)絡簡網(wǎng)絡

2015-08-06 10:49:19

銳捷

2015-07-10 10:27:23

銳捷

2014-03-14 09:41:22

銳捷網(wǎng)絡簡網(wǎng)絡

2014-04-22 09:49:57

銳捷網(wǎng)絡簡網(wǎng)絡

2014-08-20 09:26:47

銳捷網(wǎng)絡銳捷智分
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 九九热精品视频在线观看 | 精品毛片 | 激情欧美日韩一区二区 | 欧美激情国产日韩精品一区18 | 久久久久国产一级毛片 | 在线中文视频 | 国产精品免费av | 日本超碰 | 91精品国产综合久久福利软件 | 日本三级在线视频 | 亚洲欧美精品久久 | 亚洲视频在线播放 | 91亚洲免费 | 福利片在线观看 | 久久久这里都是精品 | 国产精品中文 | 午夜免费观看网站 | 日韩aⅴ片 | 国产高清视频 | 日韩精品一区二区三区中文在线 | 国产婷婷色一区二区三区 | 久久久久国产精品午夜一区 | 羞羞视频网页 | 中文成人无字幕乱码精品 | av黄色在线| 麻豆91精品91久久久 | 天堂一区二区三区 | 精品久久久久久久久亚洲 | 亚洲一区二区 | 欧美一级毛片久久99精品蜜桃 | 久久这里只有精品首页 | 日韩在线免费视频 | 99re6在线| 国产精品入口麻豆www | 亚洲激情一区二区 | 美女爽到呻吟久久久久 | 伊人网综合在线 | 99伊人网| 雨宫琴音一区二区在线 | www久| 日韩电影中文字幕 |