譯者按:JavaScript的this
和Java等面向?qū)ο笳Z(yǔ)言中的this
大不一樣,bind()
、call()
和apply()
函數(shù)更是將this
的靈活度進(jìn)一步延伸。
成都創(chuàng)新互聯(lián)專業(yè)為企業(yè)提供夏津網(wǎng)站建設(shè)、夏津做網(wǎng)站、夏津網(wǎng)站設(shè)計(jì)、夏津網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁(yè)設(shè)計(jì)與制作、夏津企業(yè)網(wǎng)站模板建站服務(wù),10余年夏津做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。
原文: JavaScript: The Keyword ‘This’ for Beginners
為了保證可讀性,本文采用意譯而非直譯。另外,本文版權(quán)歸原作者所有,翻譯僅用于學(xué)習(xí)。
如果對(duì)JavaScript的關(guān)鍵字this
理解不夠深刻,有時(shí)候會(huì)掉入意想不到的坑。在這里我們總結(jié)了5條通用規(guī)則來(lái)幫助你判斷this
到底指向什么。雖然沒(méi)有囊括所有的情況,但日常大部分情況都可以使用這些規(guī)則來(lái)正確推斷。
this
的值通常是由所在函數(shù)的執(zhí)行環(huán)境決定,也就是說(shuō)要看函數(shù)是如何被調(diào)用的;this
都可能指向不同的對(duì)象;打開Chrome瀏覽器開發(fā)者面板(Windows: Ctrl + Shift + J)(Mac: Cmd + Option + J),并且輸入:
console.log(this);
看看輸出了什么?
// Window {}
window
對(duì)象! 因?yàn)樵谌肿饔糜蛳拢?code>this指向全局對(duì)象。在瀏覽器中全局對(duì)象就是window
對(duì)象。
為了讓你更加清楚理解為什么this
會(huì)指向window
對(duì)象,我們來(lái)看另外一個(gè)例子:
var myName = 'Brandon';
我們可以通過(guò)在控制臺(tái)輸入myName
來(lái)訪問(wèn)其值:
myName
// 輸出 'Brandon'
其實(shí),所有在全局定義的變量都綁定到window
對(duì)象。我們來(lái)做如下測(cè)試:
window.myName
// 輸出 'Brandon'
window.myName === myName
// 輸出 true
現(xiàn)在我們將this
放到函數(shù)內(nèi)部,看看有何效果。
function test(){
return this;
}
test();
你會(huì)發(fā)現(xiàn)this
依然指向全局的window
對(duì)象。因?yàn)?code>this關(guān)鍵字沒(méi)有處于一個(gè)聲明的對(duì)象內(nèi)部,默認(rèn)指向全局window
對(duì)象。這一點(diǎn)可能對(duì)于大部分初學(xué)者來(lái)說(shuō)有點(diǎn)難以理解。當(dāng)讀完這篇文章,你就會(huì)豁然開朗。
注意:如果在strcit
模式下,上面的例子中this
為undefined
。
當(dāng)this
關(guān)鍵字在一個(gè)聲明對(duì)象內(nèi)部使用,其值會(huì)被綁定到調(diào)用該this
的函數(shù)的最近的父對(duì)象。我們用例子來(lái)說(shuō)明這個(gè)問(wèn)題:
var person = {
first: 'John',
last: 'Smith',
full: function() {
console.log(this.first + ' ' + this.last);
}
};
person.full();
// 輸出 '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)。
var person = {
first: 'John',
last: 'Smith',
full: function() {
console.log(this);
}
};
person.full();
// 輸出 Object {first: "John", last: "Smith", full: function}
我們接下來(lái)看一個(gè)更復(fù)雜的例子:
var person = {
first: 'John',
last: 'Smith',
full: function() {
console.log(this.first + ' ' + this.last);
},
personTwo: {
first: 'Allison',
last: 'Jones',
full: function() {
console.log(this.first + ' ' + this.last);
}
}
};
在這里我們有嵌套的對(duì)象,在這個(gè)時(shí)候,this
分別指向誰(shuí)呢? 我們將其打印出來(lái)看一看:
person.full();
// 輸出 'John Smith'
person.personTwo.full();
// 輸出 'Allison Jones'
你會(huì)發(fā)現(xià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è)例子:
function Car(make, model) {
this.make = make;
this.model = model;
};
根據(jù)第一條規(guī)則,你可能會(huì)推斷this
指向全局對(duì)象。但是如果我們使用new
關(guān)鍵字來(lái)聲明一個(gè)新的變量,Car
函數(shù)中的this
將會(huì)綁定一個(gè)新的空對(duì)象,然后初始化this.make
和this.model
的值。
var myCar = new Car('Ford', 'Escape');
console.log(myCar);
// 輸出 Car {make: "Ford", model: "Escape"}
call
, bind
, 和apply
我們可以顯示的在call()
,bind()
,apply()
中設(shè)置this
的綁定對(duì)象。這三個(gè)函數(shù)很類似,但是我們需要注意它們微小的區(qū)別。
我們來(lái)看一個(gè)例子:
function add(c, d) {
console.log(this.a + this.b + c + d);
}
add(3,4);
// 輸出 NaN
add
函數(shù)輸出NaN
, 因?yàn)?code>this.a和this.b
未定義。
現(xiàn)在我們引入對(duì)象,并且使用call()
和apply()
來(lái)調(diào)用:
function add(c, d) {
console.log(this.a + this.b + c + d);
}
var ten = {a: 1, b: 2};
add.call(ten, 3, 4);
// 輸出 10
add.apply(ten, [3,4]);
// 輸出 10
當(dāng)我們使用add.call()
,第一個(gè)參數(shù)是this
需要綁定的對(duì)象,剩下的是add
函數(shù)本來(lái)的參數(shù)。
因此,this.a
指向ten.a
,this.b
指向ten.b
。add.apply()
也類似,除了第二個(gè)參數(shù)是一個(gè)數(shù)組,用于存儲(chǔ)add
函數(shù)的參數(shù)。
bind()
函數(shù)和call()
類似,但是bind()
函數(shù)不會(huì)立即被調(diào)用。bind()
函數(shù)會(huì)返回一個(gè)函數(shù),并且將this
綁定好。接下來(lái)我們來(lái)用例子來(lái)幫助理解bind()
函數(shù)的應(yīng)用場(chǎng)景:
var small = {
a: 1,
go: function(b,c,d){
console.log(this.a+b+c+d);
}
}
var large = {
a: 100
}
執(zhí)行:
small.go(2, 3, 4);
// 輸出 10
如果我們想使用large.a
的值,而不是small.a
呢? 我們可以使用call/apply
:
small.go.call(large, 2, 3, 4);
// 輸出 109
但是,如果我們現(xiàn)在還不知道這三個(gè)參數(shù)應(yīng)該傳入什么值,應(yīng)該怎么辦呢? 我們可以使用bind
:
var bindTest = small.go.bind(large, 2);
如果我們將bindTest
在控制臺(tái)下打印出來(lái),我們會(huì)看到:
console.log(bindTest);
// 輸出 function (b,c,d){console.log(this.a+b+c+d);}
注意:該函數(shù)已經(jīng)將this
綁定到large
對(duì)象,并且傳入了第一個(gè)參數(shù)b
。所以,我們接下來(lái)是需要傳入余下的參數(shù)即可:
bindTest(3, 4);
// 輸出 109
因?yàn)樾枰艽蟮钠覀儠?huì)專門寫一篇博客來(lái)介紹。
當(dāng)你讀完這篇博客,你應(yīng)該可以理解大多數(shù)情況下this
指向的對(duì)象。
接下來(lái)我們來(lái)總結(jié)一下:
this
的值通常是由當(dāng)前函數(shù)的執(zhí)行環(huán)境所決定;this
指向全局對(duì)象 (window
對(duì)象);new
關(guān)鍵字聲明,this
指向新建對(duì)象;call()
, bind()
, apply()
來(lái)設(shè)置this
;this
。Fundebug專注于JavaScript、微信小程序、微信小游戲、支付寶小程序、React Native、Node.js和Java實(shí)時(shí)BUG監(jiān)控。 自從2016年雙十一正式上線,F(xiàn)undebug累計(jì)處理了7億+錯(cuò)誤事件,得到了Google、360、金山軟件、百姓網(wǎng)等眾多知名用戶的認(rèn)可。歡迎免費(fèi)試用!
轉(zhuǎn)載時(shí)請(qǐng)注明作者Fundebug以及本文地址:
https://blog.fundebug.com/2017/05/17/javascript-this-for-beginners/
標(biāo)題名稱:JavaScript初學(xué)者必看“this”
URL分享:http://muchs.cn/article30/jpijpo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站建設(shè)、關(guān)鍵詞優(yōu)化、企業(yè)建站、全網(wǎng)營(yíng)銷推廣、電子商務(wù)、自適應(yīng)網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)