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

前端開發初學者必須了解的“this”關鍵字

開發 開發工具
如果對JavaScript的關鍵字this理解不夠深刻,有時候會掉入意想不到的坑。在這里我們總結了5條通用規則來幫助你判斷this到底指向什么。

如果對JavaScript的關鍵字this理解不夠深刻,有時候會掉入意想不到的坑。在這里我們總結了5條通用規則來幫助你判斷this到底指向什么。雖然沒有囊括所有的情況,但日常大部分情況都可以使用這些規則來正確推斷。

  1. this的值通常是由所在函數的執行環境決定,也就是說要看函數是如何被調用的;
  2. 同一個函數每一次調用,this都可能指向不同的對象;

[[194327]]

全局對象 (Global Object)

打開Chrome瀏覽器開發者面板(Windows: Ctrl + Shift + J)(Mac: Cmd + Option + J),并且輸入:

  1. console.log(this); 

看看輸出了什么?

  1. // Window {} 

window對象! 因為在全局作用域下,this指向全局對象。在瀏覽器中全局對象就是window對象。

為了讓你更加清楚理解為什么this會指向window對象,我們來看另外一個例子:

  1. var myName = 'Brandon'

我們可以通過在控制臺輸入myName來訪問其值:

  1. myName 
  2. // 輸出 'Brandon' 

其實,所有在全局定義的變量都綁定到window對象。我們來做如下測試:

  1. window.myName 
  2. // 輸出 'Brandon' 
  3. window.myName === myName 
  4. // 輸出 true 

現在我們將this放到函數內部,看看有何效果。

  1. function test(){ 
  2. return this; 
  3. test(); 

你會發現this依然指向全局的window對象。因為this關鍵字沒有處于一個聲明的對象內部,默認指向全局window對象。這一點可能對于大部分初學者來說有點難以理解。當讀完這篇文章,你就會豁然開朗。

注意:如果在strcit模式下,上面的例子中this為undefined。

聲明的對象 (Declared Object)

當this關鍵字在一個聲明對象內部使用,其值會被綁定到調用該this的函數的最近的父對象。我們用例子來說明這個問題:

  1. var person = { 
  2. first: 'John', 
  3. last: 'Smith', 
  4. full: function() { 
  5. console.log(this.first + ' ' + this.last); 
  6. }; 
  7. person.full(); 
  8. // 輸出 'John Smith' 

在被聲明的對象person中的full函數里面使用了this, 那么調用this的full函數的最近的父對象就是person, 因此,this指向person。

為了更好的描述this實際上是指向person對象的,你可以拷貝如下代碼到瀏覽器控制臺,將this打印出來。

  1. var person = { 
  2. first: 'John', 
  3. last: 'Smith', 
  4. full: function() { 
  5. console.log(this); 
  6. }; 
  7. person.full(); 
  8. // 輸出 Object {first: "John", last: "Smith", full: function} 

我們接下來看一個更復雜的例子:

  1. var person = { 
  2. first: 'John', 
  3. last: 'Smith', 
  4. full: function() { 
  5. console.log(this.first + ' ' + this.last); 
  6. }, 
  7. personTwo: { 
  8. first: 'Allison', 
  9. last: 'Jones', 
  10. full: function() { 
  11. console.log(this.first + ' ' + this.last); 
  12. }; 

在這里我們有嵌套的對象,在這個時候,this分別指向誰呢? 我們將其打印出來看一看:

  1. person.full(); 
  2. // 輸出 'John Smith' 
  3. person.personTwo.full(); 
  4. // 輸出 'Allison Jones' 

你會發現滿足我們前面所描述的規則:其值會被綁定到調用this的函數的最近的父對象。

new關鍵字

當使用new關鍵字構建一個新的對象,this會綁定到這個新對象。我們來看一個例子:

  1. function Car(make, model) { 
  2. this.make = make; 
  3. this.model = model; 
  4. }; 

根據***條規則,你可能會推斷this指向全局對象。但是如果我們使用new關鍵字來聲明一個新的變量,Car函數中的this將會綁定一個新的空對象,然后初始化this.make和this.model的值。

  1. var myCar = new Car('Ford', 'Escape'); 
  2. console.log(myCar); 
  3. // 輸出 Car {make: "Ford", model: "Escape"} 

call, bind, 和apply

我們可以顯示的在call(),bind(),apply()中設置this的綁定對象。這三個函數很類似,但是我們需要注意它們微小的區別。

我們來看一個例子:

  1. function add(c, d) { 
  2. console.log(this.a + this.b + c + d); 
  3. add(3,4); 
  4. // 輸出 NaN 

add函數輸出NaN, 因為this.a和this.b未定義。

現在我們引入對象,并且使用call()和apply()來調用:

  1. function add(c, d) { 
  2. console.log(this.a + this.b + c + d); 
  3. var ten = {a: 1, b: 2}; 
  4. add.call(ten, 3, 4); 
  5. // 輸出 10 
  6. add.apply(ten, [3,4]); 
  7. // 輸出 10 

當我們使用add.call(),***個參數是this需要綁定的對象,剩下的是add函數本來的參數。

因此,this.a指向ten.a,this.b指向ten.b。add.apply()也類似,除了第二個參數是一個數組,用于存儲add函數的參數。

bind()函數和call()類似,但是bind()函數不會立即被調用。bind()函數會返回一個函數,并且將this綁定好。接下來我們來用例子來幫助理解bind()函數的應用場景:

  1. var small = { 
  2. a: 1, 
  3. go: function(b,c,d){ 
  4. console.log(this.a+b+c+d); 
  5. var large = { 
  6. a: 100 

執行:

  1. small.go(2, 3, 4); 
  2. // 輸出 10 

如果我們想使用large.a的值,而不是small.a呢? 我們可以使用call/apply:

  1. small.go.call(large, 2, 3, 4); 
  2. // 輸出 109 

但是,如果我們現在還不知道這三個參數應該傳入什么值,應該怎么辦呢? 我們可以使用bind:

  1. var bindTest = small.go.bind(large, 2); 

如果我們將bindTest在控制臺下打印出來,我們會看到:

  1. console.log(bindTest); 
  2. // 輸出 function (b,c,d){console.log(this.a+b+c+d);} 

注意:該函數已經將this綁定到large對象,并且傳入了***個參數b。所以,我們接下來是需要傳入余下的參數即可:

  1. bindTest(3, 4); 
  2. // 輸出 109 

箭頭函數(->)

因為需要很大的篇幅,我們會專門寫一篇博客來介紹。

結論

當你讀完這篇博客,你應該可以理解大多數情況下this指向的對象。

接下來我們來總結一下:

  1. this的值通常是由當前函數的執行環境所決定;
  2. 在全局作用域,this指向全局對象 (window對象);
  3. 當使用new關鍵字聲明,this指向新建對象;
  4. 我們可以使用call(), bind(), apply()來設置this;
  5. 箭頭函數不會綁定this。

【本文為51CTO專欄作者“謝軍”的原創稿件,轉載可通過作者微信公眾號(jingfeng18)獲取聯系】

戳這里,看該作者更多好文

責任編輯:趙寧寧 來源: 51CTO專欄
相關推薦

2011-07-11 17:45:13

java

2012-05-22 14:38:04

2018-06-29 14:42:54

編程Python開發

2017-10-30 10:12:27

安卓開發初學者技巧

2021-03-14 18:22:23

套接字網絡通信

2011-06-01 09:27:08

JavaScript

2011-09-16 09:38:19

Emacs

2022-04-24 15:21:01

MarkdownHTML

2011-04-12 10:13:24

2011-07-04 14:14:54

java

2009-09-28 09:45:00

CCNA學習經驗CCNA

2011-09-14 09:49:41

Android開發

2022-10-10 15:28:45

負載均衡

2015-07-20 13:56:59

SDN

2011-08-04 18:01:07

IOS Cocoa Touc

2020-09-08 19:03:41

Java代碼初學者

2022-07-22 13:14:57

TypeScript指南

2009-08-30 15:04:56

2010-06-13 11:13:38

UML初學者指南

2021-05-10 08:50:32

網絡管理網絡網絡性能
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩精品一区二区三区中文字幕 | 亚洲一区中文字幕 | 97精品国产97久久久久久免费 | 97超碰在线播放 | 国产91亚洲精品一区二区三区 | 成人国产精品入口免费视频 | 日日操av | 久久久久久久久久久久久久av | 四虎影院新地址 | 精品日韩| 亚洲+变态+欧美+另类+精品 | 91精品国产一区二区三区 | 国产又爽又黄的视频 | 成人性生交大片 | 午夜精品一区 | 免费一级毛片 | 久久久久中文字幕 | 国产免费视频 | 欧美日韩精品一区 | 欧美性另类 | 在线精品一区二区三区 | 91在线色视频| 日韩精品一区二区三区视频播放 | 久久夜夜 | 99国产精品99久久久久久 | 日韩精品一区二区三区中文字幕 | 久久亚洲一区二区 | 亚洲一区二区久久久 | 国产探花 | 亚洲精品一区二三区不卡 | 鲁视频| 国产精品久久精品 | 欧美二区三区 | 亚洲国产精品99久久久久久久久 | 成人片免费看 | 国产高清不卡 | 成人精品一区二区三区 | 91婷婷韩国欧美一区二区 | 亚洲一区影院 | 亚洲精品国产电影 | 在线a视频网站 |