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