JS中的this - 01
阿新 • • 發佈:2020-09-17
首先從物件開始,物件表示一系列屬性的集合,包括普通的屬性和函式,如下:
let student = {
nickname: '小明',
say: function(){
console.log('我是小明');
}
}
可以看到log的內容包含了這個物件nickname屬性的值,所以沒必要寫死,可以用this指向這個物件,也就是下面的部分:
let student = {
nickname: '小明',
say: function(){
console.log('我是' + this.nickname);
}
}
student.say();
上面的程式碼中this.nickname
student.say()
這樣的方式來使用say
這個函式的,這裡先關注呼叫的物件student
。接著,我們將say函式單獨拎出來使用:
let say = student.say;
say();
按照正常的思路,可能會以為上面還是照常輸出我是小明
,而實際上的輸出是我是undefined
,於是便會發現將say
拎出來單獨使用的時候,this.name
的值為undefined
,那為什麼會出現這種情況?
首先,檢視student.say()
與say()
這兩者的區別,很明顯前者是通過student
say()
函式的,後者沒有呼叫物件,這也就是最重要的不同點了。在JavaScript中,this是“自由”的,它的值是在呼叫時計算出來的,並不取決於方法宣告的位置,而是取決於在“點符號前”的是什麼物件。所以說,如果是
student.say()
,則this為student
,而如果就光禿禿的一個函式,也沒有“點符號”,則分為兩種情況:
- "use strict"模式下,this為
undefined
,所以會報錯; - 非strict模式下,this表示全域性物件(在網頁中是
window
物件);
這樣便可以解釋say()
中this.nickname
為什麼為undefined
了,因為window.nickname
undefined
。
接著便可以寫幾個例子:
let student = {
nickname: '小明',
say: function(){
console.log('我是' + this.nickname);
}
}
student.say(); // 我是小明
window.nickname = '小紅';
let say = student.say;
say(); // 我是小紅
let student2 = {
nickname: '小白',
}
student2.say = student.say;
student2.say(); // 我是小白
平常使用this的時候需要注意以下幾點:
- 只在物件的方法裡使用this,不要在普通的方法內使用;
- 時刻注意this的指向,特別是setTimeout、setInterval等超時函式(超時呼叫的程式碼都是在全域性作用域中執行的,因此函式中this的值在非嚴格模式下指向window物件,在嚴格模式下是undefined);
- 如果需要使用外層的this,可以先將this賦給that,然後使用that;
Vue補充部分
let LoStudent1 = {
// 因為是呼叫$root.getName(),所以值為小紅
template: `<div>{{name}}{{$root.getName()}}</div>`,
data() {
return {
name: '小明'
}
},
};
let LoStudent2 = new Vue({
el: '#app',
template: `<div>{{name}}<lo-student1></lo-student1></div>`,
data() {
return {
name: '小紅'
}
},
components: {
LoStudent1
},
methods: {
getName() {
return this.name;
}
}
})
有關this繫結與箭頭函式等問題下篇再講。