JavaScript - This 變數
為了方便在object的method下使用該object的屬性或者其他method,而建立一個名為this變數,而這個變數會是指著object本身。 另外每一個function(非簡化版本)都擁有this這內建變數,只有arrow function不存在this
舉例來說:
假如我們建立一個object給user變數(此變數就成了該instance的reference或者別名),該object的屬性為name,而方法(method)則為speak()函式
1 | const user = { |
,每當我們想要呼叫該object的speak方法時,會產生
1 | my name is |
可如果說想讓這方法去印出object本身的name,那麼就能利用下面語法來印出,其中this就這個user指向的object本身,而name則是object所擁有的屬性name
1 | speak() { |
,結果會是:
1 | my name is apple |
this 本身內容
this本身會根據呼叫者是否物件、被呼叫的函式(方法)是否為arrow function來決定指向哪個物件。
當呼叫者是物件本身且方法為一般函式(非簡化)
在這種情況下的方法會是以下形式,若我們建立了一個物件並給予person1這個別名(reference)
1 | function functionName { |
,其object會是以下內容,
1 | const person1 = { |
當我們利用person1下的myNameIs方法時,系統會解析呼叫myNameIs的物件是誰,在這裡系統會發現是person1所指向的物件呼叫該方法的
1 | person1.myNameIs() |
,接著它就直接該物件下的myNameIs()方法,同時它也會發現this這變數,在這裏由於系統已經發現是person1所指向的物件,所以this會跟著指向同個物件並允許系統獲取該物件的name,也就是John,最後螢幕顯示的結果會是:
1 | my name is John |
可如果這時我再添加另一個person2來指向另一個新的物件時,比如說
1 | const person2 = { |
那麼同樣地,我們再次下達以下程式碼:
1 | person1.myNameIs() |
系統會根據先前的解析方式來分別從person1和person2所指向的物件來獲取name的資訊並顯示以下結果
1 | my name is John |
沒有物件的時候,呼叫時的this會是?
可如果呼叫的函式存在this,但呼叫時卻沒有物件方便讓系統辨識this會指向誰。
1 | function myNameIs() { |
這時系統會預設讓這個this變數指向window這個global object,但由於window沒有name這個屬性,所以得到的結果會是:
1 | my name is undefined |
當使用arrow function的this會是?
由於arrow function本身沒有this變數,但實作上會以該function定義所在的環境是否存在其他this內建變數,若存在的話就以該this變數所指向的object為主,若不存在的話就以window這個global object為主。
舉例來說:
1 | const arrow = () => { |
程式碼中存在1.~3.這三處,第一處呼叫了位於global scope的arrow function,由該函式本身就沒有this變數,所以this會被定義成window,而第二處則是呼叫user變數指向的object之arrow方法,該方法由於定義的範圍並不存在其他this變數,因此他的this也是window,而第三處的this則是間接呼叫位於global scope的arrow 函式,所以也跟第一處一樣是指向window這object。
另一個範例為:
var func = function () {
var func2 = function () {
setTimeout(() => {
console.log(this);
}, 10);
};
var func3 = {
func: func2,
var4: 4
}
func2(); // this = window
func3.func(); // func3 Object
}
func();
藉由func來執行整個程式碼,其中我們只需要關注func2()和func3.func()這兩個函式呼叫,func2呼叫由於是本身調用週期工作來印this,this被定義到的範圍是位於func2,而他的this變數指向window,所以週期工作的this也跟著指向window,而func3.func()則是因爲func3本身是物件且func會指向func2這函式物件,這相當於func3.func2()。
由於這樣,而func2的this變數就跟著指向呼叫者-func3,因此週期任務也會跟著指向func3
參考資料:
本Blog上的所有文章除特别聲明外,均採用 CC BY-SA 4.0 協議 ,轉載請註明出處!