this的值是在運行時確定的
JS中的this究竟代表什么,這是在程序運行時根據(jù)上下文環(huán)境確定,可以分為以下幾種情況。
1. 全局作用域中的this
在全局作用域中,this指向window對象。
?
1
2
3
4
5
6
console.log(this);//指向window對象
this.x = 5//在全局作用域內(nèi)創(chuàng)建一個x
//與this.x = 5的等價情況:
//var x = 5;
//x = 5;
在全局作用域中執(zhí)行var x=5,其實是為window對象創(chuàng)建一個屬性x,并令其等于5。
若定義變量時不加var,JS會認為該變量為全局變量,會將其當作window對象的屬性。
2. 函數(shù)中的this
JS中函數(shù)有兩種,直接調(diào)用的函數(shù)稱為普通函數(shù),通過new創(chuàng)建對象的函數(shù)稱為構(gòu)造函數(shù)。
2.1 構(gòu)造函數(shù)中的this
構(gòu)造函數(shù)的this指向它所創(chuàng)建的對象,如:
?
1
2
3
4
function Person(name){
this.name = name;//this指向該函數(shù)創(chuàng)建的對象person
}
var person = new Person("chaimm");
2.2 普通函數(shù)中的this
普通函數(shù)的this指向window對象。
若上述例子,直接執(zhí)行Perosn函數(shù),則其中this代表window對象,因此該函數(shù)執(zhí)行后會創(chuàng)建一個全局的name。
?
1
2
3
4
function Person(name){
this.name = name;//this指向window
}
Person("chai");//當作普通函數(shù)執(zhí)行,this指向window對象
3. 對象中的this
對象中的this指向當前對象,如:
?
1
2
3
4
5
6
var person = {
name : "chaimm",
getName : function(){
return
this.name;
}
}
上述代碼中this指向函數(shù)getName所屬的對象。
但是,如果一個對象的函數(shù)中又嵌套了一個函數(shù),這個函數(shù)的this指向的卻是window,而并不是其外層的對象。
?
1
2
3
4
5
6
7
8
var person = {
name : "chaimm",
setName : function(name){
?。╢unction(name){
this.name = name; //此時this并不代表person對象,而是代表window對象
})(name);
}
}
上述示例中,person對象中有一個getName函數(shù),而getName函數(shù)內(nèi)部又有一個函數(shù),這個函數(shù)內(nèi)部的this指向window對象,而非person對象,這是JS的一個bug!一般作如下處理,規(guī)避這個bug:
?
1
2
3
4
5
6
7
8
9
var person = {
name : "chaimm",
setName : function(name){
var thar = this;//將this賦給that
(function(name){
that.name = name;//此時that指向person對象
})(name);
}
}
我們在person對象的第一層函數(shù)中,將this賦給局部變量that,然后在第二層函數(shù)中使用that,此時that指向person對象,可對person的屬性進行操作。
注意:若將一個對象中的函數(shù)賦給一個變量后,再通過該變量調(diào)用這個函數(shù),此時該函數(shù)中的this指向window,而非該對象,如下所示:
?
1
2
3
4
5
6
7
8
9
10
11
var person = {
name : "chaimm",
getName : function(){
return this.name;
}
}
//將getName函數(shù)賦給一個新的變量
var newGetName = person.getName;
//通過新的變量調(diào)用這個函數(shù),這個函數(shù)中的this將指向window
newGetName();//若全局作用域中沒有name,則將返回undefined
4. 用
call
和apply函數(shù)給this開掛
這兩個函數(shù)都能手動指定被調(diào)用函數(shù)內(nèi)部的this指向哪個對象。
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//定義一個構(gòu)造函數(shù)
var Person = function(name){
this.name = "";
this.setName = function(name){
this.name = name;
}
}
//創(chuàng)建兩個對象
var personA = new Person("A");
var personB = new Person("B");
//使用personA的setName函數(shù)去修改personB的name屬性
personA.setName.apply(personB,["C"];
apply用法
對象A.函數(shù)名。apply(對象B, 參數(shù)列表);
當對象B作為apply的第一個參數(shù)傳給apply時,對象A的函數(shù)中this就指向了對象B,此時對象A的該函數(shù)對this的操作將會作用在對象B上,由此實現(xiàn)了用對象A去調(diào)用對象B的函數(shù)。
/tupian/20230522/