自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

前端開(kāi)發(fā)初學(xué)者必須了解的“this”關(guān)鍵字

開(kāi)發(fā) 開(kāi)發(fā)工具
如果對(duì)JavaScript的關(guān)鍵字this理解不夠深刻,有時(shí)候會(huì)掉入意想不到的坑。在這里我們總結(jié)了5條通用規(guī)則來(lái)幫助你判斷this到底指向什么。

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

  1. this的值通常是由所在函數(shù)的執(zhí)行環(huán)境決定,也就是說(shuō)要看函數(shù)是如何被調(diào)用的;
  2. 同一個(gè)函數(shù)每一次調(diào)用,this都可能指向不同的對(duì)象;

[[194327]]

全局對(duì)象 (Global Object)

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

  1. console.log(this); 

看看輸出了什么?

  1. // Window {} 

window對(duì)象! 因?yàn)樵谌肿饔糜蛳拢瑃his指向全局對(duì)象。在瀏覽器中全局對(duì)象就是window對(duì)象。

為了讓你更加清楚理解為什么this會(huì)指向window對(duì)象,我們來(lái)看另外一個(gè)例子:

  1. var myName = 'Brandon'

我們可以通過(guò)在控制臺(tái)輸入myName來(lái)訪問(wèn)其值:

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

其實(shí),所有在全局定義的變量都綁定到window對(duì)象。我們來(lái)做如下測(cè)試:

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

現(xiàn)在我們將this放到函數(shù)內(nèi)部,看看有何效果。

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

你會(huì)發(fā)現(xiàn)this依然指向全局的window對(duì)象。因?yàn)閠his關(guān)鍵字沒(méi)有處于一個(gè)聲明的對(duì)象內(nèi)部,默認(rèn)指向全局window對(duì)象。這一點(diǎn)可能對(duì)于大部分初學(xué)者來(lái)說(shuō)有點(diǎn)難以理解。當(dāng)讀完這篇文章,你就會(huì)豁然開(kāi)朗。

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

聲明的對(duì)象 (Declared Object)

當(dāng)this關(guān)鍵字在一個(gè)聲明對(duì)象內(nèi)部使用,其值會(huì)被綁定到調(diào)用該this的函數(shù)的最近的父對(duì)象。我們用例子來(lái)說(shuō)明這個(gè)問(wèn)題:

  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' 

在被聲明的對(duì)象person中的full函數(shù)里面使用了this, 那么調(diào)用this的full函數(shù)的最近的父對(duì)象就是person, 因此,this指向person。

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

  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} 

我們接下來(lái)看一個(gè)更復(fù)雜的例子:

  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. }; 

在這里我們有嵌套的對(duì)象,在這個(gè)時(shí)候,this分別指向誰(shuí)呢? 我們將其打印出來(lái)看一看:

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

你會(huì)發(fā)現(xiàn)滿(mǎn)足我們前面所描述的規(guī)則:其值會(huì)被綁定到調(diào)用this的函數(shù)的最近的父對(duì)象。

new關(guān)鍵字

當(dāng)使用new關(guān)鍵字構(gòu)建一個(gè)新的對(duì)象,this會(huì)綁定到這個(gè)新對(duì)象。我們來(lái)看一個(gè)例子:

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

根據(jù)***條規(guī)則,你可能會(huì)推斷this指向全局對(duì)象。但是如果我們使用new關(guān)鍵字來(lái)聲明一個(gè)新的變量,Car函數(shù)中的this將會(huì)綁定一個(gè)新的空對(duì)象,然后初始化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()中設(shè)置this的綁定對(duì)象。這三個(gè)函數(shù)很類(lèi)似,但是我們需要注意它們微小的區(qū)別。

我們來(lái)看一個(gè)例子:

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

add函數(shù)輸出NaN, 因?yàn)閠his.a和this.b未定義。

現(xiàn)在我們引入對(duì)象,并且使用call()和apply()來(lái)調(diào)用:

  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 

當(dāng)我們使用add.call(),***個(gè)參數(shù)是this需要綁定的對(duì)象,剩下的是add函數(shù)本來(lái)的參數(shù)。

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

bind()函數(shù)和call()類(lèi)似,但是bind()函數(shù)不會(huì)立即被調(diào)用。bind()函數(shù)會(huì)返回一個(gè)函數(shù),并且將this綁定好。接下來(lái)我們來(lái)用例子來(lái)幫助理解bind()函數(shù)的應(yīng)用場(chǎng)景:

  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 

執(zhí)行:

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

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

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

但是,如果我們現(xiàn)在還不知道這三個(gè)參數(shù)應(yīng)該傳入什么值,應(yīng)該怎么辦呢? 我們可以使用bind:

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

如果我們將bindTest在控制臺(tái)下打印出來(lái),我們會(huì)看到:

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

注意:該函數(shù)已經(jīng)將this綁定到large對(duì)象,并且傳入了***個(gè)參數(shù)b。所以,我們接下來(lái)是需要傳入余下的參數(shù)即可:

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

箭頭函數(shù)(->)

因?yàn)樾枰艽蟮钠?,我們?huì)專(zhuān)門(mén)寫(xiě)一篇博客來(lái)介紹。

結(jié)論

當(dāng)你讀完這篇博客,你應(yīng)該可以理解大多數(shù)情況下this指向的對(duì)象。

接下來(lái)我們來(lái)總結(jié)一下:

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

【本文為51CTO專(zhuān)欄作者“謝軍”的原創(chuàng)稿件,轉(zhuǎn)載可通過(guò)作者微信公眾號(hào)(jingfeng18)獲取聯(lián)系】

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

責(zé)任編輯:趙寧寧 來(lái)源: 51CTO專(zhuān)欄
相關(guān)推薦

2011-07-11 17:45:13

java

2012-05-22 14:38:04

2018-06-29 14:42:54

編程Python開(kāi)發(fā)

2021-03-14 18:22:23

套接字網(wǎng)絡(luò)通信

2017-10-30 10:12:27

安卓開(kāi)發(fā)初學(xué)者技巧

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-09-14 09:49:41

Android開(kāi)發(fā)

2015-07-20 13:56:59

SDN

2022-10-10 15:28:45

負(fù)載均衡

2011-07-04 14:14:54

java

2009-09-28 09:45:00

CCNA學(xué)習(xí)經(jīng)驗(yàn)CCNA

2011-08-04 18:01:07

IOS Cocoa Touc

2009-11-18 09:30:43

2011-05-18 11:01:39

Oracle

2021-05-10 08:50:32

網(wǎng)絡(luò)管理網(wǎng)絡(luò)網(wǎng)絡(luò)性能

2022-03-28 09:52:42

JavaScript語(yǔ)言

2023-07-28 07:31:52

JavaScriptasyncawait
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)