函式的this指向問題一直都是困擾包括我在內的不少開發者的問題,我一直以來都是這樣看待這個問題的,函式屬于誰它的this就指向誰,直到我遇到了一個無法用這個簡單粗暴的方法辨識的場景時,我才真正弄明白,函式的this并不一定指向占有這個函式的物件,而指向呼叫這個函式的物件,從現在起請牢牢記住這句話

函式的this并不一定指向占有這個函式的物件,而指向呼叫這個函式的物件
函式的this并不一定指向占有這個函式的物件,而指向呼叫這個函式的物件
函式的this并不一定指向占有這個函式的物件,而指向呼叫這個函式的物件
雖然結論很重要,不過這個結論并不是什么新鮮玩意兒,在有關js的書籍教程里面,都能找到這個結論,廢話不多說,我通過源代碼來推導這個結論,為了簡化代碼省略<script>標簽
function test(){ console.warn('test', this) };
test();
//輸出Window {0: Window, window: Window...
控制臺輸出啥沒人不知道吧,如果不知道建議去B站補超哥的視頻,這里輸出的是window,這里的test()等價于window.test(),在script里面宣告的函式會自動變成全域的
//第一種寫法等價于
var test = function(){ console.warn('test', this) };
test();
也就是變成window的成員函式,在這里有個直觀的認識,test屬于window,所以它輸出的物件是window,但是記住這個結論是不對的
//上面兩種寫法等價于
window.test = function(){ console.warn('test', this) };
window.test();
為了阻止test提升為window的成員,我們使用es6的let/const來宣告
let test = function(){ console.warn('test', this) };
window.test();
//window.test is not a function
問題來了,這里我們直接呼叫test()控制臺輸出的是誰?結果輸出的還是window,所以直接推翻上面的說法,test不是window的成員卻仍然指向window
let test = function(){ console.warn('test', this) };
test();
//輸出Window {0: Window, window: Window...

其實只到這里,這個結論就可以驗證了,但是一定有同學不滿意,test都不是window的成員,window是怎么呼叫它的,初學者不建議在往下看,記住上面的代碼和結論就夠了,在js里面每一個函式都有一個呼叫者,如果使用匿名的形式呼叫,瀏覽器會自動幫我們補全,怎么理解這個東西呢,函式的一般呼叫形式為obj.function(),如果簡寫成function(),瀏覽器會在運行的時候自動把函式臨時加到當前作用域里面,并使用this.function()的方式呼叫,體現了js的運行時的特性
let test = function(){ console.warn('test', this) };
test();
//等價于下面的形式
let test = function(){ console.warn('test', this) };
test.call(this)
也就是使用Function原型中的call方法把this直接設定為了當前的this,而在script標簽里面this就是window,實際上所有一般的呼叫形式都會被轉化為call,下面的demo.test()等價于demo.test.call(demo)
let demo = {};
demo.test = function(){ console.warn('test', this) };
demo.test();
//輸出test {test: ?}
let demo = {};
demo.test = function(){ console.warn('test', this) };
test();
//輸出test is not defined
let demo = {};
let test = function(){ console.warn('test', this) };
demo.test = test;
test.call(demo);
//輸出test {test: ?}
let demo = {};
demo.test = function(){ console.warn('test', this) };
demo.test.call(demo);
//輸出test {test: ?}
所以其實上面的結論可以表述為,函式的this指向call函式的第一個引數,也就是call的第一個引數是誰,函式的this就指向誰,有錯誤的地方歡迎大家批評指正,有不懂可以問我
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/299697.html
標籤:其他
