周虎
摘要:JavaScript逐漸從一門簡(jiǎn)單的腳本語(yǔ)言進(jìn)化成為一門強(qiáng)大的面向?qū)ο缶幊陶Z(yǔ)言,尤其在對(duì)象的this指向上,不僅借鑒了其他高級(jí)語(yǔ)言的優(yōu)點(diǎn),并結(jié)合自身靈活的編程能力,在程序運(yùn)行中可以動(dòng)態(tài)改變this指向。該文針對(duì)this在全局變量、函數(shù)、對(duì)象中的指向,以及通過(guò)apply、call和bind改變綁定對(duì)象后this的指向進(jìn)行了深入的探討并進(jìn)行了總結(jié)歸納,便于讀者更深層次的理解JavaScript中的this指向問(wèn)題。
關(guān)鍵詞:JavaScript;this;bind;apply;call
中圖分類號(hào):TP312? ? ? 文獻(xiàn)標(biāo)識(shí)碼:A
文章編號(hào):1009-3044(2021)26-0162-02
開(kāi)放科學(xué)(資源服務(wù))標(biāo)識(shí)碼(OSID):
1 背景
JavaScript是面向Web的編程語(yǔ)言,其動(dòng)態(tài)以及面向?qū)ο蟮木幊田L(fēng)格使得它已經(jīng)從一門簡(jiǎn)單的腳本語(yǔ)言進(jìn)化成為一門強(qiáng)大的編程語(yǔ)言[1]。在高級(jí)語(yǔ)言面向?qū)ο缶幊踢^(guò)程中,都會(huì)用到this關(guān)鍵字,一般用來(lái)指向構(gòu)建的對(duì)象,同樣在JavaScript編程語(yǔ)言中,在很多情況下也會(huì)用到this關(guān)鍵字,this在其不同的上下文環(huán)境中,this的指向會(huì)各不相同,尤其在全局變量、函數(shù)和對(duì)象中的指向,以及通過(guò)apply、call和bind在改變綁定對(duì)象后this的指向問(wèn)題,對(duì)于初學(xué)者來(lái)說(shuō)很容易混淆,并因此可能導(dǎo)致程序錯(cuò)誤。本文根據(jù)this在不同上下文環(huán)境中的指向問(wèn)題進(jìn)行分類探討,便于讀者對(duì)JavaScript中的this指向問(wèn)題的理解和應(yīng)用。
2 JavaScript中的this指向分析
在JavaScript語(yǔ)言中,使用到this關(guān)鍵字的上下文通常包括全局變量、普通函數(shù)、構(gòu)造函數(shù)、對(duì)象函數(shù)和箭頭函數(shù),以及通過(guò)關(guān)鍵字apply、call和bind改變對(duì)象指向后this的指向。下面就不同情況下this的指向進(jìn)行分析探討。
2.1 全局變量和函數(shù)中this指向
在全局變量中,this默認(rèn)指向的是window對(duì)象,此時(shí)可以省略this,也可以使用window來(lái)代替,如下面代碼所示:
var str="hello JavaScript";
function fn(){
console.log(this.str);
}
this.fn();
console.log(this);
在上面代碼中this指向就是window對(duì)象,即使在普通函數(shù)fn()中,此時(shí)this也是指向的window對(duì)象,用來(lái)獲取全局變量的值。但是在ES6以后,如果改用let來(lái)定義全局變量,此時(shí)全局變量將不再是window對(duì)象的屬性了,如下面代碼所示:
let str="hello JavaScript";
console.log(str);//hello JavaScript
console.log(this.str);//undefined
在上面代碼中,可以使用變量名str直接訪問(wèn),但是不能使用this.str來(lái)訪問(wèn),因?yàn)閘et定義的全局變量不再屬于window對(duì)象,此時(shí)將輸出undefined。
2.2 構(gòu)造函數(shù)中的this指向
JavaScript可以通過(guò)構(gòu)造函數(shù)來(lái)創(chuàng)建并初始化對(duì)象,只不過(guò)JavaScript沒(méi)有類定義和特殊的構(gòu)造器定義,需要程序員自己定義一個(gè)構(gòu)造函數(shù)來(lái)創(chuàng)建屬性,而所有的函數(shù)都可以被用來(lái)定義構(gòu)造函數(shù)[2]。在構(gòu)造函數(shù)中使用this,這點(diǎn)和其他高級(jí)語(yǔ)言類似,this指向的是使用new創(chuàng)建的對(duì)象,如下面代碼所示:
function Student(name,age)
{
this.name=name;
this.age=age;
}
var stu=new Student("zhangsan",15);
console.log(stu.name);//zhangsan
在上面代碼中,構(gòu)造函數(shù)中的this就指向了使用Student函數(shù)創(chuàng)建的當(dāng)前對(duì)象stu,這一點(diǎn)和其他的高級(jí)語(yǔ)言構(gòu)造函數(shù)中的this功能類似,都是指向當(dāng)前對(duì)象本身。
2.3 對(duì)象函數(shù)中的this指向
面向?qū)ο缶幊趟枷氲闹攸c(diǎn)在“對(duì)象”上,對(duì)象實(shí)質(zhì)上是“客觀事物”在程序設(shè)計(jì)語(yǔ)言中的表現(xiàn)形式[3]。在JavaScript對(duì)象中可以使用this來(lái)訪問(wèn)對(duì)象的屬性和函數(shù),此時(shí)this的指向是當(dāng)前對(duì)象,但是如果對(duì)象的函數(shù)是其他全局函數(shù)的引用,那么全局函數(shù)中的this指向就可能發(fā)生改變,如下面代碼所示:
var name="zhangsan";
function show()
{
console.log(this.name);
}
var stu={
name:'lisi',
show:show
}
show();//輸出zhangsan
stu.show();//輸出lisi
在上面代碼中,如果直接調(diào)用show()函數(shù),則是輸出全局變量name的值”zhangsan”,但是在stu對(duì)象中的show函數(shù)是對(duì)全局函數(shù)show()的引用,stu.show()在執(zhí)行時(shí)show函數(shù)中的this則指向了stu對(duì)象,所以輸出“l(fā)isi”。
如果對(duì)象屬性還是一個(gè)對(duì)象,并且和父對(duì)象具有相同的屬性,那么this則指向當(dāng)前的屬性對(duì)象,如下面代碼所示: