摘要:綁定書中提到在中,實際上并不存在所謂的構造函數,只有對于函數的構造調用。規則使用構造調用的時候,會自動綁定在期間創建的對象上。指向新創建的對象綁定比隱式綁定優先級高。
前言
最近正在看《你不知道的JavaScript》,里面關于this綁定機制的部分講的特別好,很清晰,這部分對我們js的使用也是相當關鍵的,并且這也是一個面試的高頻考點,所以整理一篇文章分享一下這部分的內容,相信看本文的解析,你一定會有所收獲的,如果喜歡的話可以點波贊/關注,支持一下。
個人博客了解一下:obkoro1.com為什么要用this:
function identify() { console.log("Hello,I"m " + this.name); } let me = { name: "Kyle" }; let you = { name: "Reader" }; identify.call(me); // Hello,I"m Kyle identify.call(you); // Hello,I"m Reader
這個簡單的栗子,可以在不同的對象中復用函數identify,不用針對每個對象編寫一個新函數。
this解決的問題:
this提供了一種更優雅的方法來隱式"傳遞"一個對象的引用,因此可以將API設計得更加簡潔并且易于復用。
this的四種綁定規則: 默認綁定:規則:在非嚴格模式下,默認綁定的this指向全局對象,嚴格模式下this指向undefined
function foo() { console.log(this.a); // this指向全局對象 } var a = 2; foo(); // 2 function foo2() { "use strict"; // 嚴格模式this綁定到undefined console.log(this.a); } foo2(); // TypeError:a undefined
默認綁定規則如上述栗子,書中還提到了一個微妙的細節:
function foo() { console.log(this.a); // foo函數不是嚴格模式 默認綁定全局對象 } var a = 2; function foo2(){ "use strict"; foo(); // 嚴格模式下調用其他函數,不影響默認綁定 } foo2(); // 2
所以:對于默認綁定來說,決定this綁定對象的是函數體是否處于嚴格模式,嚴格指向undefined,非嚴格指向全局對象。
通常不會在代碼中混用嚴格模式和非嚴格模式,所以這種情況很罕見,知道一下就可以了,避免某些{{BANNED}}的面試題挖坑。
隱式綁定:規則:函數在調用位置,是否有上下文對象,如果有,那么this就會隱式綁定到這個對象上。
function foo() { console.log(this.a); } var a = "Oops, global"; let obj2 = { a: 2, foo: foo }; let obj1 = { a: 22, obj2: obj2 }; obj2.foo(); // 2 this指向調用函數的對象 obj1.obj2.foo(); // 2 this指向最后一層調用函數的對象 // 隱式綁定丟失 let bar = obj2.foo; // bar只是一個函數別名 是obj2.foo的一個引用 bar(); // "Oops, global" - 指向全局
隱式綁定丟失:
隱式綁定丟失的問題:實際上就是函數調用時,并沒有上下文對象,只是對函數的引用,所以會導致隱式綁定丟失。
同樣的問題,還發生在傳入回調函數中,這種情況更加常見,并且隱蔽,類似:
test(obj2.foo); // 傳入函數的引用,調用時也是沒有上下文對象。顯式綁定:
就像我們上面看到的,如果單純使用隱式綁定肯定沒有辦法得到期望的綁定,幸好我們還可以在某個對象上強制調用對象,從而將this綁定在這個函數上。
規則:我們可以通過apply、call、bind將函數中的this綁定到指定對象上。
function foo() { console.log(this.a); } let obj = { a: 2 }; foo.call(obj); // 2
傳入的不是對象:
如果你傳入了一個原始值(字符串,布爾類型,數字類型),來當做this的綁定對象,這個原始值轉換成它的對象形式。
如果你把null或者undefined作為this的綁定對象傳入call/apply/bind,這些值會在調用時被忽略,實際應用的是默認綁定規則。
new綁定:書中提到:在js中,實際上并不存在所謂的"構造函數",只有對于函數的"構造調用"。
new的時候會做哪些事情:
創建一個全新的對象。
這個新對象會被執行 [[Prototype]] 連接。
這個新對象會綁定到函數調用的this。
如果函數沒有返回其他對象,那么new表達式中的函數調用會自動返回這個新對象。
規則:使用構造調用的時候,this會自動綁定在new期間創建的對象上。
function foo(a) { this.a = a; // this綁定到bar上 } let bar = new foo(2); console.log(bar.a); // 2this四種綁定規則的優先級
如果在某個調用位置應用了多條規則,如何確定哪條規則生效?
obj.foo.call(obj2); // this指向obj2 顯式綁定比隱式綁定優先級高。 new obj.foo(); // thsi指向new新創建的對象 new綁定比隱式綁定優先級高。
顯式綁定和new綁定無法直接比較((會報錯),默認綁定是不應用其他規則之后的兜底綁定所以優先級最低,最后的結果是:
顯式綁定 > 隱式綁定 > 默認綁定
new綁定 > 隱式綁定 > 默認綁定
箭頭函數的this指向不會使用上述的四條規則:function foo() { return () => { console.log(this.a); }; } let obj1 = { a: 2 }; let obj2 = { a: 22 }; let bar = foo.call(obj1); // foo this指向obj1 bar.call(obj2); // 輸出2 這里執行箭頭函數 并試圖綁定this指向到obj2
從上述栗子可以得出,箭頭函數的this規則:
箭頭函數中的this繼承于它外面第一個不是箭頭函數的函數的this指向。
箭頭函數的 this 一旦綁定了上下文,就不會被任何代碼改變。
結語認真看完的話,相信你已經get到this的用法了,最后推薦一下《你不知道的JavaScript》,這本書真的很好,寫的也很有趣,沒看過的小伙伴抓緊入手了。
PS:目前離職中,大佬們有坑位可以介紹一下呀,base:上海長寧。
希望看完的朋友可以點個喜歡/關注,您的支持是對我最大的鼓勵。個人blog and 掘金個人主頁,如需轉載,請放上原文鏈接并署名。碼字不易,感謝支持!
如果喜歡本文的話,歡迎關注我的訂閱號,漫漫技術路,期待未來共同學習成長。
以上2018.6.30
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/95874.html
摘要:最近剛剛看完了你不知道的上卷,對有了更進一步的了解。你不知道的上卷由兩部分組成,第一部分是作用域和閉包,第二部分是和對象原型。附錄詞法這一章并沒有說明機制,只是介紹了中的箭頭函數引入的行為詞法。第章混合對象類類理論類的機制類的繼承混入。 最近剛剛看完了《你不知道的 JavaScript》上卷,對 JavaScript 有了更進一步的了解。 《你不知道的 JavaScript》上卷由兩部...
摘要:大四到校就開始了緊張的秋招。在此紀錄一下大四以來的前端面試。面試準備準備簡歷。主要是牛客網,牛客網秋招和春招都有面經分享活動,很多拿到大廠的大牛會在上面分享面試經驗。這段是調用函數的語句,調用了約好的函數,并且將數據當做參數傳入。 前言 大三下學期因為眼睛患了過敏性結膜炎,只好在家養病,錯過了寶貴的實習時間。大四到校就開始了緊張的秋招。拿到的第一個offer是一家廈門的公司,當時跟技術...
摘要:大四到校就開始了緊張的秋招。在此紀錄一下大四以來的前端面試。面試準備準備簡歷。主要是牛客網,牛客網秋招和春招都有面經分享活動,很多拿到大廠的大牛會在上面分享面試經驗。這段是調用函數的語句,調用了約好的函數,并且將數據當做參數傳入。 前言 大三下學期因為眼睛患了過敏性結膜炎,只好在家養病,錯過了寶貴的實習時間。大四到校就開始了緊張的秋招。拿到的第一個offer是一家廈門的公司,當時跟技術...
摘要:理解的函數基礎要搞好深入淺出原型使用原型模型,雖然這經常被當作缺點提及,但是只要善于運用,其實基于原型的繼承模型比傳統的類繼承還要強大。中文指南基本操作指南二繼續熟悉的幾對方法,包括,,。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。 怎樣使用 this 因為本人屬于偽前端,因此文中只看懂了 8 成左右,希望能夠給大家帶來幫助....(據說是阿里的前端妹子寫的) this 的值到底...
摘要:使用調用函數時,會自動執行以下操作創建一個全新的對象該對象會被執行連接該對象會綁定到函數調用的若函數沒有返回其他對象,表達式中的函數調用會自動返回該對象。 使用this可以減少傳入上下文對象,可以隱式傳遞一個對象引用。使API簡潔而復用,可以自動引用合適的上下文對象。 【要注意的幾個點】 1. this不一定指向自身; 2. this不一定指向函數作用域(因為作用域無法通過js代碼訪...
閱讀 2113·2021-09-06 15:02
閱讀 1740·2021-08-13 15:02
閱讀 2301·2019-08-29 14:14
閱讀 1464·2019-08-26 13:55
閱讀 547·2019-08-26 13:46
閱讀 3401·2019-08-26 11:41
閱讀 508·2019-08-26 10:27
閱讀 3257·2019-08-23 15:28