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