国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

換個思路理解Javascript中的this

開發 前端 開發工具
在網上很多文章都對 Javascript 中的 this 做了詳細的介紹,但大多是介紹各個綁定方式或調用方式下 this 的指向,于是我想有一個統一的思路來更好理解 this 指向,使大家更好判斷,以下有部分內容不是原理,而是一種解題思路。

在網上很多文章都對 Javascript 中的 this 做了詳細的介紹,但大多是介紹各個綁定方式或調用方式下 this 的指向,于是我想有一個統一的思路來更好理解 this 指向,使大家更好判斷,以下有部分內容不是原理,而是一種解題思路。

從call方法開始

call 方法允許切換函數執行的上下文環境(context),即 this 綁定的對象。

大多數介紹 this 的文章中都會把 call 方法放到***介紹,但此文我們要把 call 方法放在***位介紹,并從 call 方法切入來研究 this ,因為 call 函數是顯式綁定 this 的指向,我們來看看它如何模擬實現(不考慮傳入 null 、 undefined 和原始值):

  1. Function.prototype.call = function(thisArg) { 
  2.     var context = thisArg; 
  3.     var arr = []; 
  4.     var result; 
  5.  
  6.     context.fn = this; 
  7.  
  8.     for (let i = 1, len = arguments.length; i < len; i++) { 
  9.         arr.push('arguments[' + i + ']'); 
  10.     } 
  11.  
  12.     result = eval("context.fn(" + arr + ")"); 
  13.  
  14.     delete context.fn; 
  15.  
  16.     return result; 
  17.  

從以上代碼我們可以看到,把調用 call 方法的函數作為***個參數對象的方法,此時相當于把***個參數對象作為函數執行的上下文環境,而 this 是指向函數執行的上下文環境的,因此 this 就指向了***個參數對象,實現了 call 方法切換函數執行上下文環境的功能。

對象方法中的this

在模擬 call 方法的時候,我們使用了對象方法來改變 this 的指向。調用對象中的方法時,會把對象作為方法的上下文環境來調用。

既然 this 是指向執行函數的上下文環境的,那我們先來研究一下調用函數時的執行上下文情況。

下面我門來看看調用對象方法時執行上下文是如何的:

  1. var foo = { 
  2.     x : 1, 
  3.     getX: function(){ 
  4.         console.log(this.x); 
  5.     } 
  6. foo.getX(); 

 

從上圖中,我們可以看出getX方法的調用者的上下文是foo,因此getX方法中的 this 指向調用者上下文foo,轉換成 call 方法為foo.getX.call(foo)。

下面我們把其他函數的調用方式都按調用對象方法的思路來轉換。

構造函數中的this

  1. function Foo(){ 
  2.     this.x = 1; 
  3.     this.getX = function(){ 
  4.         console.log(this.x); 
  5.     } 
  6. var foo = new Foo(); 
  7. foo.getX();  

執行 new 如果不考慮原型鏈,只考慮上下文的切換,就相當于先創建一個空的對象,然后把這個空的對象作為構造函數的上下文,再去執行構造函數,***返回這個對象。

  1. var newMethod = function(func){ 
  2.     var context = {}; 
  3.     func.call(context); 
  4.     return context; 
  5. function Foo(){ 
  6.     this.x = 1; 
  7.     this.getX = function(){ 
  8.         console.log(this.x); 
  9.     } 
  10. var foo = newMethod(Foo); 
  11. foo.getX(); 

 

DOM事件處理函數中的this

  1. DOMElement.addEventListener('click'function(){ 
  2.  
  3.   console.log(this); 
  4.  
  5. });  

把函數綁定到DOM事件時,可以當作在DOM上增加一個函數方法,當觸發這個事件時調用DOM上對應的事件方法。

  1. DOMElement.clickHandle = function(){ 
  2.     console.log(this); 
  3. DOMElement.clickHandle(); 

 

普通函數中的this

  1. var x = 1; 
  2. function getX(){ 
  3.     console.log(this.x); 
  4. getX();  

這種情況下,我們創建一個虛擬上下文對象,然后普通函數作為這個虛擬上下文對象的方法調用,此時普通函數中的this就指向了這個虛擬上下文。

那這個虛擬上下文是什么呢?在非嚴格模式下是全局上下文,瀏覽器里是 window ,NodeJs里是 Global ;在嚴格模式下是 undefined 。

  1. var x = 1; 
  2. function getX(){ 
  3.     console.log(this.x); 
  4.  
  5. [viturl context].getX = getX; 
  6. [viturl context].getX(); 

 

閉包中的this

  1. var x = 1; 
  2. var foo = { 
  3.     x: 2, 
  4.     y: 3, 
  5.     getXY: function(){ 
  6.         (function(){ 
  7.             console.log("x:" + this.x); 
  8.             console.log("y:" + this.y);  
  9.         })(); 
  10.     } 
  11. foo.getXY();  

這段代碼的上下文如下圖:

 

這里需要注意的是,我們再研究函數中的 this 指向時,只需要關注 this 所在的函數是如何調用的, this 所在函數外的函數調用都是浮云,是不需要關注的。因此在所有的圖示中,我們只需要關注紅色框中的內容。

因此這段代碼我們關注的部分只有:

  1. (function(){ 
  2.     console.log(this.x); 
  3. })();  

與普通函數調用一樣,創建一個虛擬上下文對象,然后普通函數作為這個虛擬上下文對象的方法立即調用,匿名函數中的 this 也就指向了這個虛擬上下文。

 

參數中的this

  1. var x = 1; 
  2. var foo = { 
  3.     x: 2, 
  4.     getX: function(){ 
  5.         console.log(this.x); 
  6.     } 
  7. setTimeout(foo.getX, 1000);  

函數參數是值傳遞的,因此上面代碼等同于以下代碼:

  1. var getX = function(){ 
  2.     console.log(this.x); 
  3. }; 
  4. setTimeout(getX, 1000);  

然后我們又回到了普通函數調用的問題。

全局中的this

全局中的 this 指向全局的上下文

  1. var x = 1; 
  2. console.log(this.x); 

 

復雜情況下的this

  1. var x = 1; 
  2. var a = { 
  3.     x: 2, 
  4.     b: function(){ 
  5.         return function(){ 
  6.             return function foo(){ 
  7.                 console.log(this.x); 
  8.             }         
  9.         } 
  10.     } 
  11. }; 
  12.  
  13. (function(){ 
  14.     var x = 3; 
  15.     a.b()()(); 
  16. })();  

看到上面的情況是有很多個函數,但我們只需要關注 this 所在函數的調用方式,首先我們來簡化一下如下:

  1. var x = 1; 
  2. (function(){ 
  3.     var x = 3; 
  4.     var foo = function(){ 
  5.         console.log(this.x); 
  6.     } 
  7.     foo(); 
  8. });  

this 所在的函數 foo 是個普通函數,我們創建一個虛擬上下文對象,然后普通函數作為這個虛擬上下文對象的方法立即調用。因此這個 this指向了這個虛擬上下文。在非嚴格模式下是全局上下文,瀏覽器里是 window ,NodeJs里是 Global ;在嚴格模式下是 undefined 。

總結

在需要判斷 this 的指向時,我們可以安裝這種思路來理解:

  • 判斷 this 在全局中OR函數中,若在全局中則 this 指向全局,若在函數中則只關注這個函數并繼續判斷。
  • 判斷 this 所在函數是否作為對象方法調用,若是則 this 指向這個對象,否則繼續操作。
  • 創建一個虛擬上下文,并把this所在函數作為這個虛擬上下文的方法,此時 this 指向這個虛擬上下文。
  • 在非嚴格模式下虛擬上下文是全局上下文,瀏覽器里是 window ,Node.js里是 Global ;在嚴格模式下是 undefined 。

圖示如下: 

責任編輯:龐桂玉 來源: segmentfault
相關推薦

2022-07-29 11:06:47

架構開發

2012-12-25 09:38:41

JavaScript設計模式

2020-08-23 11:32:21

JavaScript開發技術

2024-07-18 10:12:04

2022-08-16 09:03:01

JavaScript前端

2020-12-16 09:47:01

JavaScript箭頭函數開發

2021-01-06 08:03:00

JavaScript數據結構

2011-03-22 09:49:15

JavaScript

2015-09-14 15:23:44

JavaScriptfunction

2015-09-02 11:22:36

JavaScript實現思路

2020-10-12 08:35:22

JavaScript

2013-11-05 13:29:04

JavaScriptreplace

2016-11-22 11:08:34

asyncjavascript

2017-11-20 16:17:50

智慧城市

2025-12-05 08:22:06

2018-05-10 14:20:18

前端JavaScript深拷貝

2016-09-18 20:53:16

JavaScript閉包前端

2024-06-21 08:32:24

2020-02-20 14:00:15

JavaScript原型原型鏈

2023-02-08 08:47:13

計算機網絡MAC
點贊
收藏

51CTO技術棧公眾號

在线亚洲成人| 国产精品欧美日韩一区| 青青操综合网| cao在线视频| 国产精品老牛| 在线精品视频小说1| 国产精品三级久久久久久电影| 亚洲精品综合久久中文字幕| 视频在线观看成人| 女人黄色免费在线观看| 日韩av在线播放中文字幕| 色综合久久66| 高清日韩一区| 超碰在线观看免费版| 国产偷自视频区视频一区二区| 136fldh精品导航福利| 伊人影院综合在线| 女同久久另类99精品国产| 日韩精品在线免费| 一女被多男玩喷潮视频| 国产毛片久久久| 国产拍揄自揄精品视频麻豆| 欧美亚洲国产日本| 在线三级av| 在线日韩中文| 亚洲精品丝袜日韩| av资源在线看片| 亚洲免费电影一区| 国产一区二区主播在线| 中文字幕一区二区三区在线播放| 成人激情视频网| a视频在线播放| 欧美日韩国产另类一区| 一区二区不卡在线| 欧美精品羞羞答答| 亚洲精品一区av在线播放| 91福利在线免费| 亚洲一区www| 天堂资源中文在线| 国产99精品国产| 日本在线观看天堂男亚洲| 黄色一级大片在线免费看产| 97精品久久久久中文字幕| 国产欧美一区二区三区在线看| 91在线看黄| 91影院在线观看| 成人免费淫片95视频观看网站| 精品91久久久久| 欧美老女人性视频| 成黄免费在线| 久久久国产一区二区三区四区小说 | 亚洲毛片一区二区| 久久久久亚洲精品中文字幕| 高跟丝袜一区二区三区| 日韩在线视频在线| 91tv官网精品成人亚洲| 在线观看成人黄色| 最色在线观看| av亚洲产国偷v产偷v自拍| 亚洲一区二区三区乱码aⅴ蜜桃女 亚洲一区二区三区乱码aⅴ | 欧美精品v日韩精品v韩国精品v| www黄色av| 日韩和欧美一区二区三区| 国产成+人+综合+亚洲欧洲| 92国产精品| 欧美性色视频在线| www.浪潮av.com| 秋霞午夜鲁丝一区二区老狼| 日韩av中文字幕第一页| 午夜在线观看免费一区| 欧美一级免费视频| 亚洲一本视频| 国产一区视频免费观看| 精品一区二区三区视频| 国产精品手机视频| 色婷婷一区二区三区| 欧美交受高潮1| 涩涩网在线视频| 日韩三级免费观看| 在线观看av网| 亚洲美女视频网| 精品国产精品| 超薄肉色丝袜足j调教99| 欧美涩涩视频| 亚洲自拍偷拍在线| 成人晚上爱看视频| 91午夜在线观看| 久久精品国产999大香线蕉| 成人激情视频网| 成人黄色综合网站| 国内外成人激情免费视频| 欧美日韩国产精品一区二区三区四区| 中文字幕乱码在线播放| 精品成人一区二区三区四区| 自拍视频在线免费观看| 欧美高清电影在线看| 日韩久久一区| 亚洲女同性videos| 你懂的国产精品| 国产成人精品福利一区二区三区 | 91干在线观看| 国产精品白丝jk黑袜喷水| 伊人色综合影院| 久久先锋资源| 日本一区视频在线播放| 亚洲国产一区二区三区高清| 国产黄色特级片| 亚洲福利在线看| bbw在线视频| av资源一区二区| 一本色道精品久久一区二区三区 | 国产在线精品不卡| 青青青青草视频| 精品日韩一区二区三区| 色综合亚洲图丝熟| 久久www免费人成精品| 免费高清视频精品| 国产精彩视频一区二区| 欧美日韩三级视频| 欧美aaaa视频| 国产欧美日韩一区| 日韩综合一区二区| 亚洲s色大片| 亚洲第一网站免费视频| aa国产精品| 男人的天堂在线视频免费观看| 欧美精品一区二区三区在线| 在线视频观看日韩| 福利视频在线播放| 亚洲美女福利视频网站| 免费在线视频一区| 青草av在线| 在线视频一二三区| 国产精品久久久久影院老司| bdsm精品捆绑chinese女| 色狠狠av一区二区三区| 麻豆影院在线| 精品一区二区日本| 成人动漫一区二区| 天天综合av| 国产一线二线三线女| 中文字幕亚洲综合久久| 日韩系列在线| 欧美aaaaa喷水| 久久先锋资源网| 在线香蕉视频| 91精品入口蜜桃| 成人av在线资源网站| 日韩天堂在线| 国产自产女人91一区在线观看| 亚洲综合一区二区三区| 三区四区在线视频| 欧美在线播放一区二区| 久久久久久久久免费| 久久精品国产亚洲5555| 91九色极品视频| 欧美性猛交xxxx免费看漫画| 午夜电影亚洲| 1024在线播放| 国产成人av网址| 色婷婷狠狠综合| 亚洲一区网站| 巨胸喷奶水www久久久| 国产精品拍拍拍| 555夜色666亚洲国产免| 国产精品成人3p一区二区三区| 91美女片黄在线观| 久久亚洲捆绑美女| 天堂网av成人| 午夜老司机在线观看| 粉嫩av一区二区三区天美传媒| 欧美精品videossex88| 欧美日韩激情网| 国产综合成人久久大片91| 伊人久久影院| 成人在线免费高清视频| 久久久久久网址| 欧美日韩精品一区视频| 国产在线播放一区| 欧美在线色图| 黄色一级免费大片| 亚洲精品日韩在线| 综合久久久久久| 成人va天堂| 伊人精彩视频| 色偷偷av亚洲男人的天堂| 亚洲大片av| 国产91亚洲精品久久久| 欧美极品色图| 五月婷婷久久综合| 欧美大片91| 国产理论电影在线观看| 国产中文字幕乱人伦在线观看| 青草成人免费视频| 99久久伊人精品| 无需播放器亚洲| 在线小视频网址| 国产精品www在线观看| 91在线观看免费观看 | 午夜剧场成人观在线视频免费观看|