摘要:遵循以下規(guī)則,按優(yōu)先級排列。換句話說,當處于被調用函數的左邊,則就是左邊的對象。試一下通過兩種不同的方式調用函數時的值。找到應用的規(guī)則很顯然應用的是規(guī)則使用符號。在使用工具庫時發(fā)現取值不符合上述規(guī)則時,請查看庫文檔。
翻譯自文章The Simple Rules to ‘this’ in Javascript。
確定什么是 this 并非難事。總的來說,通過查找函數被調用時的位置(和方法)就可以決定。遵循以下規(guī)則,按優(yōu)先級排列。
規(guī)則
通過 new 關鍵字調用構造函數,函數內的 this 是一個全新的對象。
function ConstructorExample() { console.log(this); this.value = 10; console.log(this); } new ConstructorExample(); // -> {} // -> { value: 10 }
通過 apply 、 call 或 bind 調用一個函數,函數內的 this 就是傳入的參數。
function fn() { console.log(this); } var obj = { value: 5 }; var boundFn = fn.bind(obj); boundFn(); // -> { value: 5 } fn.call(obj); // -> { value: 5 } fn.apply(obj); // -> { value: 5 }
如果一個函數作為對象的方法調用,即使用 . 符號調用該函數, this 是調用該函數的對象。換句話說,當 . 處于被調用函數的左邊,則 this 就是左邊的對象。
var obj = { value: 5, printThis: function() { console.log(this); } }; obj.printThis(); // -> { value: 5, printThis: ? }
如果函數作為普通函數調用,意味著調用方式不符合以上任意一種, this 就是全局對象。在瀏覽器中就是 window 。
function fn() { console.log(this); } // If called in browser: fn(); // -> Window {stop: ?, open: ?, alert: ?, ...}
*這個規(guī)則可以類比于規(guī)則3——不同之處在于這個函數自動掛載到了 window 對象上,所以可以這么理解,當我們調用 fn() 時其實調用的事 window.fn() ,所以 this 就是 window 。
console.log(fn === window.fn); // -> true
如果符合上述多個規(guī)則,則越前面的規(guī)則會決定 this 的值。
如果函數是一個 ES2015 箭頭函數,會忽略上述所有規(guī)則, this 設置為它被創(chuàng)建時的上下文。為了找到 this 的值,需要找到函數被創(chuàng)建時的環(huán)境中 this 的值。
const obj = { value: "abc", createArrowFn: function() { return () => console.log(this); } }; const arrowFn = obj.createArrowFn(); arrowFn(); // -> { value: "abc", createArrowFn: ? }
我們返回去看規(guī)則3,當我們調用 obj.createArrowFn() 時, createArrowFn 中的 this 就是 obj 對象,我們用 . 符號調用。如果我們在全局中創(chuàng)建一個箭頭函數, this 就是 window 。
應用規(guī)則下面在幾個例子中應用一下我們的規(guī)則。試一下通過兩種不同的方式調用函數時 this 的值。
找到應用的規(guī)則var obj = { value: "hi", printThis: function() { console.log(this); } }; var print = obj.printThis; obj.printThis(); // -> {value: "hi", printThis: ?} print(); // -> Window {stop: ?, open: ?, alert: ?, ...}
obj.printThis() 很顯然應用的是規(guī)則3——使用 . 符號。 print() 應用了規(guī)則4,在調用 print() 時,我們沒有使用 new 、 bind/call/apply 或 . 符號,所以這里的 this 是全局對象 window 。
多重規(guī)則應用如上文提到,當應用多個規(guī)則時,優(yōu)先應用前面的規(guī)則。
var obj1 = { value: "hi", print: function() { console.log(this); }, }; var obj2 = { value: 17 };
如果規(guī)則2和3同時應用,規(guī)則2優(yōu)先。
obj1.print.call(obj2); // -> { value: 17 }
如果規(guī)則1和3同時應用,規(guī)則1優(yōu)先。
new obj1.print(); // -> {}關于工具庫
一些 JavaScript 庫有時候會在函數中主動綁定它認為最有用的內容到 this 上。比如在 JQuery中,在觸發(fā)事件時 DOM 元素被綁定到了 this 上。在使用工具庫時發(fā)現取值不符合上述規(guī)則時,請查看庫文檔。很可能使用了 bind 語法。
該文章首發(fā)于我的個人站點
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/94366.html
摘要:過去滾動捕捉只能通過實現,但現在得益于新的滾動捕捉模塊,這種效果已經可以通過實現了。同時令人慶幸的是瀏覽器可以根據用戶的滾動方式自動控制并判斷是否利用捕捉點捕捉。 特別聲明,本文翻譯自@alligatorio的Control Page Scroll in CSS Using Scroll Snapping一文,受限于譯者能力,譯文或存在不足,歡迎大家指出。如需轉載,煩請注明出處。 滾...
摘要:過去滾動捕捉只能通過實現,但現在得益于新的滾動捕捉模塊,這種效果已經可以通過實現了。同時令人慶幸的是瀏覽器可以根據用戶的滾動方式自動控制并判斷是否利用捕捉點捕捉。 特別聲明,本文翻譯自@alligatorio的Control Page Scroll in CSS Using Scroll Snapping一文,受限于譯者能力,譯文或存在不足,歡迎大家指出。如需轉載,煩請注明出處。 滾...
摘要:被解構的數據項位于賦值運算符的右側,可以是任何數組和對象的組合,允許隨意嵌套。數組模式位于賦值運算符的左側,被結構的數組在其右側。 解構是ES6的新特性,用于從JavaScript對象和數組中提取數據,語法上比ES5所提供的更加簡潔、緊湊、清晰。它不僅能減少你的代碼量,還能從根本上改變你的編碼方式。用的越多,你就會發(fā)現越多塑造數據和函數的方式,這些實現方式在過去幾乎是不可能的。本文將深...
摘要:每個字節(jié)后必須跟一個響應位。低速率一般是同一個板子上的兩個芯片間通信,數據量不大,速率低。速率幾百,速率可能不同,不能超過的最高速率。 介紹:I2C通訊協(xié)議(Inter-Integrated Circuit)引腳少,硬件實現簡單,可擴展性強,不需要USART、CAN等通訊協(xié)議的外部收發(fā)設備,...
閱讀 2306·2021-11-23 10:09
閱讀 2885·2021-10-12 10:11
閱讀 2594·2021-09-29 09:35
閱讀 1337·2019-08-30 15:53
閱讀 2261·2019-08-30 11:15
閱讀 2904·2019-08-29 13:01
閱讀 2290·2019-08-28 18:15
閱讀 3363·2019-08-26 12:13