精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

圖文并茂詳解Javascript上下文與作用域

開發 前端
Js是一門很有趣的語言,由于它的很多特性是針對HTML中DOM的操作,因而顯得隨意而略失嚴謹,但隨著前端的不斷繁榮發展和Node的興起,Js已經不再是“toy language”或是jQuery時代的“CSS擴展”,本文提到的這些概念無論是對新手還是從傳統Web開發中過度過來的Js開發人員來說,都很容易被混淆或誤解,希望本文可以有所幫助。

本文嘗試闡述Javascript中的上下文與作用域背后的機制,主要涉及到執行上下文(execution context)、作用域鏈(scope chain)、閉包(closure)、this等概念。

Execution context

執行上下文(簡稱上下文)決定了Js執行過程中可以獲取哪些變量、函數、數據,一段程序可能被分割成許多不同的上下文,每一個上下文都會綁定一個變 量對象(variable object),它就像一個容器,用來存儲當前上下文中所有已定義或可獲取的變量、函數等。位于最頂端或最外層的上下文稱為全局上下文(global context),全局上下文取決于執行環境,如Node中的global和Browser中的window

 

需要注意的是,上下文與作用域(scope)是不同的概念。Js本身是單進程的,每當有function被執行時,就會產生一個新的上下文,這一上 下文會被壓入Js的上下文堆棧(context stack)中,function執行結束后則被彈出,因此Js解釋器總是在棧頂上下文中執行。在生成新的上下文時,首先會綁定該上下文的變量對象,其中 包括arguments和該函數中定義的變量;之后會創建屬于該上下文的作用域鏈(scope chain),***將this賦予這一function所屬的Object,這一過程可以通過下圖表示:

js context stack

this

上文提到this被賦予function所屬的Object,具體來說,當function是定義在global對中時,this指向global;當function作為Object的方法時,this指向該Object:

 

  1. var x = 1
  2. var f = function(){ 
  3.   console.log(this.x); 
  4. f();  // -> 1 
  5.  
  6. var ff = function(){ 
  7.   this.x = 2
  8.   console.log(this.x); 
  9. ff(); // -> 2 
  10. x     // -> 2 
  11.  
  12. var o = {x: "o's x", f: f}; 
  13. o.f(); // "o's x" 

上文提到,在function被執行時生成新的上下文時會先綁定當前上下文的變量對象,再創建作用域鏈。我們知道function的定義是可以嵌套 在其他function所創建的上下文中,也可以并列地定義在同一個上下文中(如global)。作用域鏈實際上就是自下而上地將所有嵌套定義的上下文所 綁定的變量對象串接到一起,使嵌套的function可以“繼承”上層上下文的變量,而并列的function之間互不干擾:

js scope chain

 

  1. var x = 'global'
  2. function a(){ 
  3.   var x = "a's x"
  4.   function b(){ 
  5.     var y = "b's y"
  6.     console.log(x); 
  7.   }; 
  8.   b(); 
  9. function c(){ 
  10.   var x = "c's x"
  11.   function d(){ 
  12.     console.log(y); 
  13.   }; 
  14.   d(); 
  15. a();  // -> "a's x" 
  16. c();  // -> ReferenceError: y is not defined 
  17. x     // -> "global" 
  18. y     // -> ReferenceError: y is not defined 

Closure

如果理解了上文中提到的上下文與作用域鏈的機制,再來看閉包的概念就很清楚了。每個function在調用時會創建新的上下文及作用域鏈,而作用域 鏈就是將外層(上層)上下文所綁定的變量對象逐一串連起來,使當前function可以獲取外層上下文的變量、數據等。如果我們在function中定義 新的function,同時將內層function作為值返回,那么內層function所包含的作用域鏈將會一起返回,即使內層function在其他 上下文中執行,其內部的作用域鏈仍然保持著原有的數據,而當前的上下文可能無法獲取原先外層function中的數據,使得function內部的作用域 鏈被保護起來,從而形成“閉包”。看下面的例子:

  1. var x = 100
  2. var inc = function(){ 
  3.   var x = 0
  4.   return function(){ 
  5.     console.log(x++); 
  6.   }; 
  7. }; 
  8.  
  9. var inc1 = inc(); 
  10. var inc2 = inc(); 
  11.  
  12. inc1();  // -> 0 
  13. inc1();  // -> 1 
  14. inc2();  // -> 0 
  15. inc1();  // -> 2 
  16. inc2();  // -> 1 
  17. x;       // -> 100 

執行過程如下圖所示,inc內部返回的匿名function在創建時生成的作用域鏈包括了inc中的x,即使后來賦值給inc1inc2之后,直接在global context下調用,它們的作用域鏈仍然是由定義中所處的上下文環境決定,而且由于x是在function inc中定義的,無法被外層的global context所改變,從而實現了閉包的效果:

js closure

this in closure

我們已經反復提到執行上下文和作用域實際上是通過function創建、分割的,而function中的this與作用域鏈不同,它是由**執行該function時**當前所處的Object環境所決定的,這也是this最容易被混淆用錯的一點。一般情況下的例子如下:

  1. var name = "global"
  2. var o = { 
  3.   name: "o"
  4.   getName: function(){ 
  5.     return this.name 
  6.   } 
  7. }; 
  8. o.getName();  // -> "o" 

由于執行o.getName()getName所綁定的this是調用它的o,所以此時this == o;更容易搞混的是在closure條件下:

  1. var name = "global"
  2. var oo = { 
  3.   name: "oo"
  4.   getNameFunc: function(){ 
  5.     return function(){ 
  6.       return this.name; 
  7.     }; 
  8.   } 
  9. oo.getNameFunc()();  // -> "global" 

此時閉包函數被return后調用相當于:

  1. getName = oo.getNameFunc(); 
  2. getName();  // -> "global" 

換一個更明顯的例子:

  1. var ooo = { 
  2.   name: "ooo"
  3.   getName: oo.getNameFunc() // 此時閉包函數的this被綁定到新的Object 
  4. }; 
  5. ooo.getName();  // -> "ooo" 

當然,有時候為了避免閉包中的this在執行時被替換,可以采取下面的方法:

  1. var name = "global"
  2. var oooo = { 
  3.   name: "ox4"
  4.   getNameFunc: function(){ 
  5.     var self = this
  6.     return function(){ 
  7.        return self.name; 
  8.     }; 
  9.   } 
  10. }; 
  11. oooo.getNameFunc()(); // -> "ox4" 

或者是在調用時強行定義執行的Object:

  1. var name = "global"
  2. var oo = { 
  3.   name: "oo"
  4.   getNameFunc: function(){ 
  5.     return function(){ 
  6.       return this.name; 
  7.     }; 
  8.   } 
  9. oo.getNameFunc()();  // -> "global" 
  10. oo.getNameFunc().bind(oo)(); // -> "oo" 

總結

Js是一門很有趣的語言,由于它的很多特性是針對HTML中DOM的操作,因而顯得隨意而略失嚴謹,但隨著前端的不斷繁榮發展和Node的興 起,Js已經不再是“toy language”或是jQuery時代的“CSS擴展”,本文提到的這些概念無論是對新手還是從傳統Web開發中過度過來的Js開發人員來說,都很容易 被混淆或誤解,希望本文可以有所幫助。

寫這篇總結的原因是我在Github上分享的Learn javascript in one picture,剛開始有人質疑這只能算是一張語法表(syntax cheat sheet),根本不會涉及更深層的閉包、作用域等內容,但是出乎意料的是這個項目竟然獲得3000多個star,所以不能虎頭蛇尾,以上。

責任編輯:王雪燕 來源: rainyear的博客
相關推薦

2011-11-21 15:12:54

Java斷點Eclipse

2011-08-03 15:21:23

ORM XCode 數據庫

2011-07-04 16:57:36

QT 布局 界面

2012-07-27 10:27:19

OfficeWord

2023-05-05 07:41:42

執行上下文JavaScript

2022-09-14 13:13:51

JavaScript上下文

2011-01-18 18:08:28

Thunderbird

2011-01-18 18:29:28

Thunderbird

2011-07-18 13:11:53

2011-01-19 17:34:39

Postfix如何接收郵件

2023-05-16 08:01:13

架構網站演進

2011-01-19 17:30:21

Postfix郵件投遞

2012-07-23 14:39:27

移動

2011-01-20 09:13:18

Postfix

2021-12-27 08:04:49

架構網站高并發

2011-08-09 16:47:24

Xcode 4發布程序

2020-07-24 10:00:00

JavaScript執行上下文前端

2011-01-19 10:30:20

UbuntuThunderbird

2022-07-18 14:33:05

PythonPDF報告

2011-01-21 10:28:06

點贊
收藏

51CTO技術棧公眾號

欧美一区亚洲二区| 一区二区三区日韩在线| 久久久久福利视频| 日韩性xxxx| 视频一区二区欧美| 久久艳片www.17c.com | 粉嫩嫩av羞羞动漫久久久| 欧美日韩福利电影| 熟女少妇内射日韩亚洲| 国产精品欧美大片| 欧美日韩亚洲国产综合| 农民人伦一区二区三区| 91xxx在线观看| 国产91高潮流白浆在线麻豆| 国产精品久久久久久久久免费看 | 波多野结衣在线网站| 国产成人自拍网| 国产成人久久精品| 欧美成人aaaaⅴ片在线看| 成久久久网站| 亚洲国产婷婷香蕉久久久久久| 岛国毛片在线播放| 成人私拍视频| 性做久久久久久免费观看欧美| 一本久道久久综合| 成人免费高清在线播放| av一二三不卡影片| 懂色av一区二区三区在线播放| 在线观看国产精品视频| 亚洲一区二区毛片| 国内精品久久久久影院 日本资源 国内精品久久久久伊人av | 91精品国产毛片武则天| 91在线导航| 久久一区二区三区国产精品| 成人精品水蜜桃| 国产精品无码久久av| 日本系列欧美系列| 日韩av不卡在线| 国产精品美女久久久久av爽| 国产精品大片| 欧美日韩国产成人在线观看| 侵犯稚嫩小箩莉h文系列小说| 久久视频在线| 日韩在线观看免费全集电视剧网站| 久久精品国产亚洲av久| 天天久久夜夜| 日韩精品免费观看| 日本xxx在线播放| 欧美a大片欧美片| 亚洲第一精品夜夜躁人人躁| 香蕉久久久久久av成人| 日韩精品一区二区三区中文字幕 | 成人在线视频免费播放| 国产ts一区| 亚洲精品suv精品一区二区| 性活交片大全免费看| 88久久精品| 亚洲国产精品va在线观看黑人| 亚洲色图欧美另类| 美腿丝袜亚洲图片| 亚洲毛片在线免费观看| 制服 丝袜 综合 日韩 欧美| 精品美女久久久| 中文字幕日韩综合av| 中文字幕美女视频| 欧美~级网站不卡| 欧美激情a在线| 一级免费在线观看| 丝袜美腿亚洲一区| 国产91精品最新在线播放| 瑟瑟视频在线免费观看| 久久99久久久欧美国产| 91网免费观看| 欧洲免费在线视频| 亚洲欧美自拍偷拍| 国产欧美久久久久| 欧美日韩精品免费观看视完整| 欧美三级在线播放| 黑人无套内谢中国美女| 欧美重口另类| 色琪琪综合男人的天堂aⅴ视频| 农村黄色一级片| 亚洲在线网站| 成人免费看片视频| 亚洲av毛片成人精品| 欧美激情中文不卡| 国产成人在线小视频| 欧美xo影院| 日韩亚洲欧美成人一区| 国产精品一区二区入口九绯色| 第九色区aⅴ天堂久久香| 欧美成人免费全部观看天天性色| 国产尤物在线视频| 国产综合久久久久久久久久久久| 久久av一区二区三区漫画| av亚洲在线| 午夜激情综合网| 思思久久精品视频| 三级精品视频| 欧美另类精品xxxx孕妇| 无码人妻一区二区三区线| 国产激情一区二区三区桃花岛亚洲| 免费试看一区| 免费电影视频在线看| 欧美亚日韩国产aⅴ精品中极品| 亚洲成人福利视频| 97精品视频| 国产成人涩涩涩视频在线观看| 国产成人精品一区二三区四区五区| 久久久综合激的五月天| 97在线免费视频观看| 欧美日韩在线精品一区二区三区激情综合| 欧美tickling网站挠脚心| 国产又黄又粗的视频| 一本色道久久精品| 成人一区二区在线| 拍真实国产伦偷精品| 欧美特黄级在线| 制服丝袜在线第一页| 国产二区精品| 国产精品香蕉av| 欧美18xxxxx| 欧美日韩国产综合新一区| 少妇性l交大片7724com| 色喇叭免费久久综合| 国产精品久久久久久超碰| 凸凹人妻人人澡人人添| 亚洲精品你懂的| 欧洲熟妇精品视频| 亚洲深夜福利在线观看| 91精品91久久久久久| 亚洲av综合色区无码一二三区| 中文字幕一区在线观看| 天天色综合天天色| 成人看的羞羞网站| 国产精品福利在线观看网址| 欧美女v视频| 色综合天天综合色综合av | 刘亦菲久久免费一区二区| 亚洲欧美日韩久久| 日本成人xxx| 影视一区二区| 成人国产一区二区| 91九色porn在线资源| 亚洲成人av在线播放| 国产午夜精品无码| 99视频有精品| 日韩欧美精品在线观看视频| 婷婷成人在线| 国产精品福利小视频| 午夜毛片在线| 91精品国产综合久久久蜜臀粉嫩 | 国产精品三上| 欧洲精品码一区二区三区免费看| www.成人爱| 国产午夜一区二区| 中文字幕一区二区三区人妻四季| 欧美国产日韩精品免费观看| 免费看污污网站| 91精品国产成人观看| 亚洲在线免费视频| heyzo高清国产精品| 日韩av在线天堂网| 懂色av蜜臀av粉嫩av分享吧最新章节| 中文幕一区二区三区久久蜜桃| 久久久久久久久久一区| 亚洲无线一线二线三线区别av| 国产日韩欧美一区二区| 欧美理论影院| 久久精品视频中文字幕| 成人精品在线播放| 欧美视频中文字幕在线| 国产成人在线网址| 成人av综合在线| 亚洲人成无码www久久久| 天天做天天爱天天爽综合网| 成人免费在线看片| 欧美影视资讯| 欧美国产亚洲视频| 免费在线观看污视频| 在线不卡的av| wwwxxx亚洲| 亚洲欧洲av色图| 不卡一区二区在线观看| 久久国产视频网| 色欲色香天天天综合网www| 精品一区在线| 亚洲综合成人婷婷小说| 欧美片第一页| 欧美精品激情视频| 在线国产91| 精品电影一区二区三区 | 久久99这里只有精品| 人妻av中文系列| 天天综合精品| 欧美一区二区在线| youjizz亚洲| 国产精品入口夜色视频大尺度| 黑人玩欧美人三根一起进| 在线不卡国产精品| 午夜国产在线观看| 日韩午夜精品视频| 国产真人无遮挡作爱免费视频| 一区二区三区在线视频观看58 | 国产精品女人久久久久久| 波多野结依一区| 久久精品欧美视频| 91福利在线视频| 日韩精品在线播放| 亚洲精品久久久蜜桃动漫| 在线观看91精品国产入口| 日韩福利片在线观看| 一区二区三区视频在线观看| 久久午夜精品视频| 91丨九色丨国产丨porny| 精产国品一区二区三区| 久草在线在线精品观看| 亚洲少妇久久久| 亚洲专区一区二区三区| 欧美 日韩 亚洲 一区| 亚洲情侣在线| 二级片在线观看| 成人综合久久| 丝袜美腿玉足3d专区一区| 亚洲免费福利一区| 久久99精品久久久久久久久久| 奇米一区二区| 444亚洲人体| 日韩三级不卡| 99精品99久久久久久宅男| 在线成人免费| 国产又爽又黄的激情精品视频| 日韩一级二级| 国产免费一区二区三区在线能观看| 国产精品扒开腿做爽爽爽视频软件| 国产91精品不卡视频| 蜜桃av在线播放| 欧美亚洲第一页| 欧美18—19sex性hd| 欧亚精品在线观看| 欧美自拍电影| 国产精品入口尤物| 亚洲国产精选| 亚洲综合精品一区二区| 日本亚洲视频| 福利视频一区二区三区| 丁香综合av| 久久精品人成| 欧美在线免费看视频| 一区二区在线观| 在线中文字幕第一区| 六月婷婷激情综合| 亚洲东热激情| 国产一区二区三区精彩视频 | 亚洲网色网站| 亚洲乱码日产精品bd在线观看| 欧美日韩理论| 少妇人妻在线视频| 日日夜夜免费精品视频| 亚洲xxx在线观看| 国产福利91精品一区| av av在线| 国产欧美日韩三区| 一级性生活免费视频| 一级女性全黄久久生活片免费| 黄色小说在线观看视频| 欧美日韩亚洲视频一区| 久久精品五月天| 欧美精品粉嫩高潮一区二区| 国产丰满果冻videossex| 亚洲精品电影网在线观看| 久蕉在线视频| 欧美精品免费看| 成人香蕉视频| 亚洲字幕一区二区| 九九在线精品| 米仓穗香在线观看| 香蕉精品999视频一区二区| 自拍偷拍21p| 成人av在线观| 极品蜜桃臀肥臀-x88av| 亚洲激情图片一区| 无码无套少妇毛多18pxxxx| 91精品国产色综合久久| 台湾av在线二三区观看| 日韩有码在线播放| 秋霞伦理一区| 91精品天堂| 成人午夜国产| 成人一区二区免费视频| 蜜桃视频在线观看一区二区| 国产成人av片| 国产精品免费人成网站| 日本网站免费观看| 欧美高清激情brazzers| 青青草在线视频免费观看| 欧美wwwxxxx| 美女网站视频一区| 国产在线精品一区二区中文| 久久人人88| av免费网站观看| 不卡一区二区中文字幕| 美女视频久久久| 91精品福利视频| 亚洲色欧美另类| 欧美激情18p| 免费观看亚洲天堂| 午夜视频久久久| 国产农村妇女毛片精品久久莱园子 | 精品国产不卡一区二区| 欧美一区二区三区成人久久片| 在线成人欧美| 美女流白浆视频| 亚洲欧美国产高清| 亚洲一级在线播放| 亚洲天堂网站在线观看视频| 免费一二一二在线视频| 99热国产免费| 欧美~级网站不卡| 日韩a一级欧美一级| 欧美国产激情一区二区三区蜜月| 天天操天天摸天天干| 亚洲精品xxxx| aa国产成人| 国产嫩草一区二区三区在线观看| 欧美黄色免费| 日本少妇一区二区三区| 亚洲你懂的在线视频| 亚洲一级在线播放| 日韩一区二区精品视频| 四虎国产精品免费久久| 一道精品一区二区三区| 蜜臀av亚洲一区中文字幕| 91精品久久久久久久久久久久| 色婷婷一区二区三区四区| 青青九九免费视频在线| 国产成人精品免高潮在线观看| 欧美女优在线视频| 日韩欧美精品在线观看视频| 久久午夜国产精品| 高清乱码免费看污| 亚洲最新视频在线| 97精品国产99久久久久久免费| 日韩高清专区| 麻豆精品国产传媒mv男同| 综合 欧美 亚洲日本| 欧美人与z0zoxxxx视频| 91麻豆免费在线视频| 99精品国产一区二区| 激情国产一区| 久久精品老司机| 欧美午夜免费电影| 黄在线免费观看| 国产精品久久久久久久久久久久冷| 在线观看视频免费一区二区三区| 中文视频在线观看| 色久优优欧美色久优优| 95在线视频| av一本久道久久波多野结衣| 亚洲特级毛片| 女尊高h男高潮呻吟| 精品视频在线看| 污污视频在线看| 精品伦精品一区二区三区视频| 久久久久国产精品午夜一区| 阿v天堂2014| 日韩一区二区三区观看| 国产黄色大片在线观看| 欧美日韩一区二区三区在线观看免 | 91精品久久久久久久久久另类 | 中文字幕在线观看日| 亚洲精品国久久99热| 亚洲 欧美 激情 另类| 国产欧美婷婷中文| 欧美网站在线| 国产美女免费无遮挡| 欧美夫妻性生活| 在线看片国产福利你懂的| 亚洲欧洲一区二区在线观看| 国产麻豆视频精品| 福利网址在线观看| 麻豆乱码国产一区二区三区| 午夜精品福利影院| 日韩成人av免费| 欧美天天综合色影久久精品| 日本在线人成| 久久亚洲精品欧美| 激情丁香综合五月| 丰满人妻老熟妇伦人精品| 久久手机精品视频| 国产成人ay| 亚洲成年人av| 欧美精品丝袜中出| 亚洲精品动漫| 日韩在线视频在线| 国产精品你懂的在线欣赏| 五月婷婷伊人网| www日韩av| 久久99国产精品久久99| 天堂中文在线网|