iT邦幫忙

4

[筆記][JavaScript]認識JavaScript中的「this」

在JavaScript中不論什麼時候執行程式碼,他都是在執行環境裡面執行,而他的基礎執行環境就是「全域執行環境」,當JavaScript在建立這個「全域執行環境」時會創造兩個東西,第一個是全域物件Global Object,另一個就是此篇文章要講的主題,一個特殊的變數:this

一開始說JavaScript不論何時執行都一定會創造這兩個東西,因為程式碼已經在建立出來的「執行環境」中執行了,也就是說,就算我們在沒有任何程式碼的情況下去呼叫this他也不會是undefined或是出錯,如下:
https://ithelp.ithome.com.tw/upload/images/20180303/20106935HsxD50kgOM.jpg
在執行環境被建立的狀況下,他可以決定this裡面是什麼,而在「全域執行環境」中的this就代表這個「瀏覽器的視窗」,因為我在瀏覽器中執行JavaScript,所以這時候的this也就是window物件,如下:
https://ithelp.ithome.com.tw/upload/images/20180303/20106935XMnHIYdhY8.jpg
所以說當在「全域執行環境」中宣告一個全域變數,就可以把this當物件一樣去調用他,例如:

//宣告全域變數Astr
var Astr = 'A';
//宣告一個印出this中Astr的funciton
var func = function(){
    console.log(this.Astr);
};

func();  //會輸出A

在「全域執行環境」中宣告一個變數,那這個變數就會像特性一樣,建立在window物件中,所以當我們在全域環境執行func()的時候,就等於是印出window.Astr的值,而我們也能夠在console中看到他,如下:
https://ithelp.ithome.com.tw/upload/images/20180303/20106935dd0vknMuLa.jpg
但是this也不會永遠是window物件,當他出現在物件內的時候this則會代表this所在的該物件,例如:

//建立一個物件A
var objA = {
    name:'A',
    writeName:function(){
        console.log(this.name);
    }
};

objA.writeName();  //會輸出A

因為writeName()這個function是透過objA執行的,所以這時候的this就會變成objA,不是window,接下來繼續舉個例子:

//建立一個物件A
var objA = {
    name:'A',
    writeName:function(){
        console.log(this.name);
    },
    objB:{
        name:'B',
        writeName:function(){
            console.log(this.name);
        },
    }
};

objA.objB.writeName();  //會輸出B

雖然writeName()這個function還是在objA內,但他其實是在objA中的特性objB內被呼叫,所以這時候的this會是objB,而不是objA也不是window

最後我們看個比較容易混淆的:

//宣告全域變數name
var name = '_this';

//建立一個物件A
var objA = {
    name:'A',
    writeName:function(){
        //在writeName特性裡面宣告一個印出this.name的function並執行他
        var writeNameB = function(){
        console.log(this.name)
        };
        writeNameB();
    },
};

objA.writeName();  //會輸出_this

這個答案是不是很令人驚訝!我們把程式碼拆開來看,一般來說在調用writeName()這個function的時候是以objA去調用的,所以他的this.name應該會是'A',但是!那是在writeName()裡面的情況下,在上面的例子中真正印出this.name的function是writeNameB(),而我們在writeName()裡面執行writeNameB()的時候並沒有在任何物件下調用他,這時候的this就不會指向該物件,而會是「全域執行環境」中的window,所以他會印出的this.name就會等於window.name,也就是印出全域變數的name也就是_this。

當然還有很多可以應用到this的地方,例如onclick事件中的參數this可以回傳觸發的Element之類的,不過因為這篇主要在講JavaScript中的this,如果有機會下次再打一篇文章說明。

如果我有觀念錯誤或解釋不清楚的地方,還麻煩各位大大指點了,謝謝大家!


1 則留言

0
fysh711426
iT邦研究生 4 級 ‧ 2018-03-06 11:09:38

原來全域宣告的 var 會等於 window 的屬性,平常使用都沒有注意到這點。
/images/emoticon/emoticon33.gif

我就一般在寫JS也不需要去注意啦XD

我要留言

立即登入留言