摘要:使用調(diào)用函數(shù)時(shí),會(huì)自動(dòng)執(zhí)行以下操作創(chuàng)建一個(gè)全新的對(duì)象該對(duì)象會(huì)被執(zhí)行連接該對(duì)象會(huì)綁定到函數(shù)調(diào)用的若函數(shù)沒有返回其他對(duì)象,表達(dá)式中的函數(shù)調(diào)用會(huì)自動(dòng)返回該對(duì)象。
使用this可以減少傳入上下文對(duì)象,可以隱式傳遞一個(gè)對(duì)象引用。使API簡(jiǎn)潔而復(fù)用,可以自動(dòng)引用合適的上下文對(duì)象。
【要注意的幾個(gè)點(diǎn)】1. this不一定指向自身; 2. this不一定指向函數(shù)作用域(因?yàn)樽饔糜驘o法通過js代碼訪問,它存在js引擎內(nèi)部); 3. this是在運(yùn)行時(shí)(函數(shù)被調(diào)用時(shí))綁定的,不是編寫代碼時(shí)綁定。this的綁定取決于函數(shù)的調(diào)用位置,不是函數(shù)聲明的位置; 4. 不能通過this來引用一個(gè)詞法作用域內(nèi)部的東西
####【找this的指向】
分析調(diào)用棧(為了到達(dá)當(dāng)前執(zhí)行位置所調(diào)用的所有函數(shù)),找到當(dāng)前正在執(zhí)行的函數(shù)的前一個(gè)調(diào)用,即調(diào)用棧的第二個(gè)元素。因?yàn)楹瘮?shù)被調(diào)用時(shí),會(huì)創(chuàng)建一個(gè)活動(dòng)記錄(執(zhí)行上下文)。該活動(dòng)記錄包括(函數(shù)的調(diào)用棧、傳入的參數(shù)、函數(shù)的調(diào)用方法……)
[方法]:在代碼前插入一條debugger語句,在開發(fā)者工具中查看call stack中的第二個(gè)元素,就是this的調(diào)用位置.
function first(){ //當(dāng)前調(diào)用棧first //當(dāng)前的調(diào)用位置是全局作用域 console.log("first"); second();//second的調(diào)用位置 } function second(){ //當(dāng)前調(diào)用棧first->second //當(dāng)前的調(diào)用位置是first console.log("second"); third();//third的調(diào)用位置 } function third(){ //當(dāng)前調(diào)用棧first->second->third //當(dāng)前的調(diào)用位置是second console.log("third"); } //first的調(diào)用位置 first();//firstsecondthird【四條this規(guī)則】:
1.默認(rèn)綁定(綁定到全局對(duì)象),但嚴(yán)格模式下this會(huì)綁定到undefin
ed:
【例子】:不帶任何修飾的函數(shù)調(diào)用
function example(){ console.log(this.a); } var a="karine"; example(); //karine
2.隱式綁定
(在一個(gè)對(duì)象內(nèi)部包含一個(gè)指向函數(shù)的屬性,通過該屬性間接地引用函數(shù),從而把this間接地綁定到該對(duì)象上。)
function example(){ console.log(this.a); } var obj={ a:"karine", example:example }; obj.example(); //karine
在對(duì)象屬性引用鏈中,只有最頂層(最后一層)會(huì)影響調(diào)用位置。
function example(){ console.log(this.a); } var obj1={ a:"karine", example:example }; var obj2={ a:"wu", obj1:obj1 }; obj2.obj1.example(); //karine
當(dāng)函數(shù)引用有上下文對(duì)象時(shí),函數(shù)里的this綁定在這個(gè)上下文對(duì)象上。
但是這種情況可能會(huì)出現(xiàn)“隱式丟失”,即丟失綁定的對(duì)象,應(yīng)用默認(rèn)綁定(全局對(duì)象/undefinded):
1. 將函數(shù)引用賦值給一個(gè)新變量,然后執(zhí)行。 var obj3 = obj1.example; obj3(); //全局or undefined 實(shí)際上obj3引用的是example函數(shù)本身,因此this還是指向全局/undefined 2. 或者是調(diào)用回調(diào)函數(shù)的函數(shù)修改了this function test(fn){ fn(); } test(obj1.example); //全局or undefined 實(shí)際上,參數(shù)傳遞也是一種賦值,只不過是隱式賦值。所以道理同上。也會(huì)指向全局。
3.顯式綁定
(在對(duì)象上強(qiáng)制調(diào)用函數(shù),可以使用call(對(duì)象)、apply(對(duì)象)方法,會(huì)把形參里的對(duì)象綁定到this上,接著在調(diào)用函數(shù)時(shí)指定這個(gè)this。如果傳入的參數(shù)為原始值(string、number、boolean),該原始值會(huì)自動(dòng)轉(zhuǎn)為其對(duì)象形式(new String()、new Number()、new Boolean()),這通常被稱為“裝箱”)
function example(){ console.log(this.a); } var obj = { a:"karine" }; example.call(obj); //karine example.apply(obj);//karine var o = example.bind(obj); o(); //karine “硬綁定”bind 的this不會(huì)被顯示or隱式綁定修改。
4.new綁定
在js中,構(gòu)造函數(shù)只是使用new操作符是被調(diào)用的普通函數(shù)而已,不屬于某個(gè)類,也不會(huì)實(shí)例化一個(gè)類。使用new調(diào)用函數(shù)時(shí),會(huì)自動(dòng)執(zhí)行以下操作:
1.創(chuàng)建一個(gè)全新的對(duì)象 2.該對(duì)象會(huì)被執(zhí)行[[prototype]]連接 3.該對(duì)象會(huì)綁定到函數(shù)調(diào)用的this 4.若函數(shù)沒有返回其他對(duì)象,new表達(dá)式中的函數(shù)調(diào)用會(huì)自動(dòng)返回該對(duì)象。
function example(a){ this.a=a; } var obj4 = new example(“karine”); console.log(obj4.a);//“karine”【四種this綁定方法的優(yōu)先級(jí)】
new綁定 > 顯式綁定 >隱式綁定 > 默認(rèn)綁定
【例外】:
1.null、undefined作為this的綁定對(duì)象傳入call、apply、bind時(shí),會(huì)被忽略,實(shí)際應(yīng)用的是默認(rèn)綁定(全局對(duì)象)
function example(){ console.log("a:"+this.a); } var a = "karine"; example.call(null); //a:karine
傳入null的情況:
(1)使用apply來展開一個(gè)數(shù)組
(2)使用bind進(jìn)行柯里化
function example(a,b){ console.log("a:"+a+“,b:”+b); } //使用apply來展開一個(gè)數(shù)組 example.apply(null,[2,3]); //a:2,b:3 //使用bind進(jìn)行柯里化(預(yù)先設(shè)置一些參數(shù)) var o = example.bind(null,2); o(3);//a:2,b:3
若想避免不必要的this綁定,可以使用ES6的…操作符來代替apply()
example.apply(null,[2,3]) === example(…[2,3])
為了安全,若想忽略this綁定,可以給this傳入一個(gè)空的非委托對(duì)象Φ ("Object.create(null)"),不會(huì)產(chǎn)生任何副作用,因?yàn)閠his會(huì)限制在這個(gè)空對(duì)象中,不會(huì)對(duì)全局對(duì)象產(chǎn)生任何影響。
**Object.create(null)**和{}很像,但是不會(huì)創(chuàng)建object.prototype,所以比{}“更空”
var Φ = Object.create(null); example.apply(Φ,[2,3]); //a:2,b:3 var o = example.bind(Φ,2); o(3); //a:2,b:3
2.間接引用(經(jīng)常在賦值時(shí)發(fā)生),會(huì)應(yīng)用默認(rèn)綁定。
3.ES6中 "=>"定義的箭頭函數(shù)不使用this的四種標(biāo)準(zhǔn)規(guī)則。而是根據(jù)外層作用域來決定this。箭頭函數(shù)的綁定無法修改。
function example(){ return(a)=>{ console.log(this.a); } } var obj1={a:2}; var obj2={a:3}; var test = example.call(obj1); test.call(obj2); //2
由于example()的this綁定到obj1,所以test中引用箭頭函數(shù)的this也會(huì)綁定到obj1。
【總結(jié)】:1.找到this的調(diào)用位置
2.根據(jù)四條規(guī)則判定this的綁定對(duì)象:
(1)new:綁定到新創(chuàng)建的對(duì)象 (2)call、apply、bind:綁定到指定的對(duì)象 (3)上下文對(duì)象:綁定到該上下文對(duì)象 (4)默認(rèn):全局或者undefined(嚴(yán)格模式下)
3.箭頭函數(shù)根據(jù)當(dāng)前的詞法作用域來決定this
4.有些調(diào)用可能無意中使用默認(rèn)規(guī)則,可以使用一個(gè)空對(duì)象Object.create(null)忽略this綁定,來保護(hù)全局對(duì)象
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/89611.html
摘要:綁定書中提到在中,實(shí)際上并不存在所謂的構(gòu)造函數(shù),只有對(duì)于函數(shù)的構(gòu)造調(diào)用。規(guī)則使用構(gòu)造調(diào)用的時(shí)候,會(huì)自動(dòng)綁定在期間創(chuàng)建的對(duì)象上。指向新創(chuàng)建的對(duì)象綁定比隱式綁定優(yōu)先級(jí)高。 showImg(http://ww1.sinaimg.cn/large/005Y4rCogy1fstcwvzkjzj30sg0g0qqn.jpg); 前言 最近正在看《你不知道的JavaScript》,里面關(guān)于this綁...
摘要:中,實(shí)例化一個(gè)對(duì)象,會(huì)用到關(guān)鍵字。這里再解釋一下構(gòu)造函數(shù)我們一般把后面的函數(shù)稱為構(gòu)造函數(shù),如,其中就為構(gòu)造函數(shù)第四點(diǎn)的,可能比較難理解。有點(diǎn)需要注意如果構(gòu)造函數(shù)內(nèi)沒有返回值,則默認(rèn)是返回當(dāng)前上下文,要不然就返回任意非原始類型值。 Javascript中,實(shí)例化一個(gè)對(duì)象,會(huì)用到new關(guān)鍵字。 經(jīng)常有人會(huì)問對(duì)于一個(gè)函數(shù),什么時(shí)候該使用new關(guān)鍵字。 在回答這個(gè)問題之前,需要先了解清楚new...
摘要:理解的函數(shù)基礎(chǔ)要搞好深入淺出原型使用原型模型,雖然這經(jīng)常被當(dāng)作缺點(diǎn)提及,但是只要善于運(yùn)用,其實(shí)基于原型的繼承模型比傳統(tǒng)的類繼承還要強(qiáng)大。中文指南基本操作指南二繼續(xù)熟悉的幾對(duì)方法,包括,,。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。 怎樣使用 this 因?yàn)楸救藢儆趥吻岸耍虼宋闹兄豢炊?8 成左右,希望能夠給大家?guī)韼椭?...(據(jù)說是阿里的前端妹子寫的) this 的值到底...
摘要:本內(nèi)容來自你不知道的上卷,做了簡(jiǎn)單的總結(jié)。如果不使用這段代碼該如何寫呢那就需要給和顯示傳入一個(gè)上下文對(duì)象對(duì)比發(fā)現(xiàn)提供了額一種更優(yōu)雅的方式來隱式傳遞一個(gè)對(duì)象引用。四總結(jié)隨著你使用的模式越來越復(fù)雜,顯式傳遞上下文對(duì)象會(huì)讓代碼變得越來越混亂。 本內(nèi)容來自《你不知道的JavaScript(上卷)》,做了簡(jiǎn)單的總結(jié)。 this關(guān)鍵字是javascript最復(fù)雜的機(jī)制之一。它是一個(gè)很特別的關(guān)鍵字,...
摘要:但是如果非全局的變量如果被遮蔽了,無論如何都無法被訪問到。但是如果引擎在代碼中找到,就會(huì)完全不做任何優(yōu)化。結(jié)構(gòu)的分句中具有塊級(jí)作用域。第四章提升編譯器函數(shù)聲明會(huì)被提升,而函數(shù)表達(dá)式不會(huì)被提升。 本書屬于基礎(chǔ)類書籍,會(huì)有比較多的基礎(chǔ)知識(shí),所以這里僅記錄平常不怎么容易注意到的知識(shí)點(diǎn),不會(huì)全記,供大家和自己翻閱; 上中下三本的讀書筆記: 《你不知道的JavaScript》 (上) 讀書筆記...
閱讀 2009·2021-11-24 09:39
閱讀 1878·2019-08-30 15:55
閱讀 2168·2019-08-30 15:53
閱讀 565·2019-08-29 13:16
閱讀 984·2019-08-26 12:20
閱讀 2379·2019-08-26 11:58
閱讀 3129·2019-08-26 10:19
閱讀 3296·2019-08-23 18:31