學習JavaScript也有一陣子,當有人問起This是什麼,都無法解釋的很清楚,代表理解的不夠徹底,今天來複習This的指向,是進入Vue之前,必須掌握的觀念之一。
影響 This 的是在於函式的呼叫方法,並非宣告的時機
,以下的程式碼來理解這句話的意思,這邊用var來示範。
var demo = '全域變數';
function callDemo() {
console.log(this.demo);
}
var obj = {
demo: '物件',
callDemo(){
console.log(this.demo);
}
}
callDemo();
console.log的結果是
。
。
。
全域變數,This的指向關鍵在於如何呼叫他,注意呼叫函式前一個的”物件“
,約有九成的This是這樣指向,
接下來我們把CallDemo()前面加個物件。
var demo = '全域變數';
function callDemo() {
console.log(this.demo);
}
var obj = {
demo: '物件',
callDemo(){
console.log(this.demo);
}
}
obj.callDemo();
console.log的結果是
。
。
。
物件,由這點來證明This的指向是跟呼叫方式有關係,再來幾個例子。
var demo = '全域變數';
function callDemo() {
console.log(this.demo);
}
var warpobj = {
demo: '外層物件',
callDemo,
innerObj: {
demo: '內層物件',
callDemo,
}
}
warpobj.callDemo();
callDemo()前面的物件是warpobj,console.log結果當然是外層物件,再來一個陷阱題。
var demo = '全域變數';
function callDemo() {
console.log(this.demo);
}
var warpobj = {
demo: '外層物件',
callDemo,
innerObj: {
demo: '內層物件',
callDemo,
}
}
warpobj.innerObj.callDemo();
console.log結果是
。
。
。
。
內層物件,注意呼叫函式前一個的”物件“
不用管innerOnj前面的物件。
var demo = '全域變數';
function callDemo() {
console.log(this.demo);
}
var obj2 = {
demo: '物件2',
fu() {
callDemo();
}
}
obj2.fu();
console.log結果是全域,原因是callDemo()前面並沒有物件,所以This指向變成全域。
最後一個範例:
var demo = '全域變數';
function callDemo() {
var demo = "測試"
console.log(this.demo);
}
var obj4 = {
demo: '物件2',
fu() {
setTimeout(function() {
console.log(this.demo);
},100)
}
}
obj4.fu();
結果是全域,Callback function大部分的This都是指向全域,只有少部分會重新定義,要避免指向跑向全域有兩種解法。
第一種解法:
var demo = '全域變數';
function callDemo() {
var demo = "測試"
console.log(this.demo);
}
var obj4 = {
demo: '物件2',
fu() {
const vm = this
setTimeout(function() {
console.log(vm.demo);
},100)
}
}
obj4.fu();
將This指向變數vm,讓他指向固定住。
第二種解法:
var demo = '全域變數';
function callDemo() {
var demo = "測試"
console.log(this.demo);
}
var obj4 = {
demo: '物件2',
fu() {
const vm = this
setTimeout(() => {
console.log(vm.demo);
},100)
}
}
obj4.fu();
把setTimeout改成箭頭函式,因為箭頭函式沒有自己的This
,所以This會外層的函式找就是fu(),結果跟第一個解法ㄧ樣都會是'物件2'。
Execution Context(Global)
不論何時執行JavaScript程式,都會是在執行環境內執行,我們常用的瀏覽器Browser,執行環境(Execution Context)就是你的全域執行環境(Global),Global創造了兩件事,創造了全域物件(Global Object)和特殊變數This,你還沒寫程式的時候,就已經有這兩個東西的存在,當你在開發者工具的console輸入windowc或This,會跳出長長一串的內容:
之後再補上這段JavaScript:
var a = 'hello world!!';
function b(){
};
開發者工具就會出現我們輸入的JavaScript:
或是直接輸入this.a或是windows.a都會有'hello world!!'的結果,代表Global Object也是一個window物件,全域情況下window也等於this,this參照window物件,但前提是執行環境要在瀏覽器Browser執行,如果是Node那情況就會不同。
卡斯柏
重新認識 JavaScript
克服JS的奇怪部分 2-10