摘要:首發個人博客中的,大家都用過。箭頭函數,詞法作用域中的簡單的說,箭頭函數中的,會綁定到函數外也就是上一層作用域中的,函數外的指向哪,箭頭函數中的就指向哪。
首發個人博客
JavaScript 中的 this ,大家都用過。但是它到底指向哪里呢?今天在閱讀 《你不知道的JavaScript (上卷)》再結合自己平時看的博客,對它又有了新的認識,在此來做個小結,再碰到 this ,就再也不用擔心不知道它指向哪里了。與調用位置有關,而與定義位置無關
以下示例(在瀏覽器端運行)
function sayHi(){ var hi = 1; console.log(this.hi); } var hi = 2; var obj = { hi : 3, sayHi : sayHi } // output sayHi(); // 2 obj.sayHi(); // 3
從上述代碼的執行結果我們可以看出,直接調用 sayHi() 函數,它輸出的 this.hi 不指向函數體內自己定義的 hi 變量,也就是說,this 的指向與詞法作用域無關,這也是剛接觸 JavaScript的同學常犯的一個錯誤(包括我自己),認為 this.xx 就指向函數體里面定義的變量 xx。sayHi函數的只定義了一次,但obj.sayHi() 與 sayHi() 的輸出結果不一樣,也恰恰證明了 函數體內this的指向與函數定義的位置無關,而與函數被調用的位置有關,至于為什么輸出結果不一樣,在下文會講到。
this 的綁定規則 默認綁定默認綁定比較常見,表現形式就是在全局作用域中獨立調用,如上文中的 sayHi(),這種直接調用方式函數體內的 this 就應用了默認綁定規則,默認綁定有以下兩種情況。
在嚴格模式下(指在函數聲明的過程中,處在嚴格模式,而不是函數調用處于嚴格模式),函數體內 this 綁定到 undefined
在非嚴格模式下,函數體內 this 指向全局對象 window
/***** 以下例子為處在嚴格模式下 *****/ function fn1(){ "use strict" console.log(this); } fn1(); // undefined /***** 以下例子處于非嚴格模式下被調用 *****/ function fn2(){ console.log(this); } fn2(); // window function fn3(){ console.log(this); } /* * 這也是在非嚴格模式下被調用 * 因為在函數定義時沒有用嚴格模式 */ "use strict" fn3(); // window隱式綁定
隱式綁定的常見形式為 obj.fn(),若obj對象中有 fn 這個方法(fn可以在別處定義,但必須被添加到obj中作為obj的一個屬性方法),那么 fn 中的 this 就指向 obj 對象,如最開始代碼中 obj.sayHi() 輸出3,就是因為sayHi中的this隱式綁定到obj對象。(個人覺得默認綁定中綁定到window對象時也可以歸類為隱式綁定,因為在全局對象中,非嚴格模式且不考慮ES6的話,所有的全局變量都自動成為window的屬性)。來看個具有迷惑性的例子(出自于原書)
function foo() { console.log( this.a ); } var obj = { a: 2, foo: foo }; var bar = obj.foo; // 函數別名! var a = "oops, global"; // a 是全局對象的屬性 bar(); // "oops, global"
這是個具有迷惑性的例子,obj 對象有函數 foo 這個方法,后面又在全局作用域中,bar 引用了這個方法,最后再調用 bar。我們只需要關注函數最后被調用的位置,它是在全局作用域中被多帶帶調用的,所以還是為默認綁定,指向 window
顯式綁定顯示綁定就比較簡單了,用 call,apply,bind方法,都會綁定函數中的this到傳入的參數對象中
new 綁定所謂new綁定就是在用構造函數new一個對象的時候,其中的this指向生成的對象。這就完了嘛?還沒有哦。
箭頭函數,詞法作用域中的this簡單的說,箭頭函數中的this,會綁定到函數外(也就是上一層作用域中的this),函數外的this指向哪,箭頭函數中的this就指向哪。(代碼出自于原書)
function foo() { // 返回一個箭頭函數 return (a) => { //this 繼承自 foo() console.log( this.a ); }; } var obj1 = { a:2 }; var obj2 = { a:3 }; var bar = foo.call( obj1 ); /* * foo先綁定this到obj1對象上,所以foo內的this指向obj1, * 返回的箭頭函數根據詞法作用域規則,繼承了外部foo的this, * 所以箭頭函數中的this指向obj1 */ bar.call( obj2 ); // 2, 不是 3 ! /* * 箭頭函數中this一但綁定,不可更改 * 此時還是指向obj1 * 所以輸出的是 obj1.a => 2 */綁定的優先級
new > 顯示 > 隱式 > 默認
上述知識來自《你不知道的JavaScript(上卷)》
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/98320.html
摘要:一等公民對象函數在提指向問題之前,肯定是有必要說明一等公民對象,既然是對象,那么就能像普通的值一樣傳遞。在普通瀏覽器中指向的是在中指向的是全局對象全局環境中或者模塊環境中。即指向或者的第一個參數。第二條規則,指向的不是原文鏈接 1. 一等公民對象——函數 在提this指向問題之前,肯定是有必要說明一等公民對象function ,既然function是對象,那么就能像普通的值一樣傳遞。嗯...
摘要:匿名函數的執行環境具有全局性,因此它的對象通常指向。如果對此有疑惑,可以看知乎上的答案知乎匿名函數的指向為什么是作為對象方法的調用,指向該對象當函數作為某個對象的方法調用時,就指這個函數所在的對象。 因為日常工作中經常使用到this,而且在JavaScript中this的指向問題也很容易讓人混淆一部分知識。 這段時間翻閱了一些書籍也查閱了網上一些資料然后結合自己的經驗,為了能讓自...
摘要:閉包閉包是指有權訪問另一個函數作用域中的變量的函數當某個函數被調用時,會創建一個執行環境及相應的作用域鏈。要注意通過第句聲明的這個方法屬于構造函數生成的對象,而不屬于構造函數的變量對象,也就是說,并不存在于作用域鏈中。 看到評論里有仁兄建議我試試箭頭函數,真是受寵若驚,本來寫這篇文章也只是想記錄寫要點給自己日后看的。今天早上看到一篇總結javascript中this的文章JavaScr...
摘要:而改變了這種狀態,雖然定義的類用運算符得到的仍然是,但它不能像普通函數一樣直接調用同時,中定義的方法函數,也不能當作構造函數用來調用。而在中,用調用一個構造函數,會創建一個新對象,而其中的就指向這個新對象。 JavaScript 中的 this 指向問題有很多博客在解釋,仍然有很多人問。上周我們的開發團隊連續兩個人遇到相關問題,所以我不得不將關于前端構建技術的交流會延長了半個時候討論 ...
摘要:調用在中,通過的形式調用一個構造函數,會創建這個構造函數實例,而這個實例的指向創建的這個實例。如下例所示,在構造函數內部使用并沒有改變全局變量的值。顯然,箭頭函數是不能用來做構造函數。 關于javascript中this指向的問題,現總結如下,如有不正確,歡迎指正。 javascript中,this的指向并不是在函數定義的時候確定的,而是在其被調用的時候確定的。也就是說,函數的...
閱讀 1640·2023-04-25 20:36
閱讀 2049·2021-09-02 15:11
閱讀 1177·2021-08-27 13:13
閱讀 2653·2019-08-30 15:52
閱讀 4589·2019-08-29 17:13
閱讀 1001·2019-08-29 11:09
閱讀 1491·2019-08-26 11:51
閱讀 833·2019-08-26 10:56