摘要:的綁定和函數(shù)聲明的位置沒有任何關(guān)系,只取決于函數(shù)的調(diào)用方式。這是一種顯示的強(qiáng)制綁定,稱為硬綁定。調(diào)用的上下文調(diào)用的時(shí)候把綁定到綁定關(guān)于,有一個(gè)重要的點(diǎn)實(shí)際上并不存在所謂的構(gòu)造函數(shù),只有對(duì)于函數(shù)的構(gòu)造調(diào)用。
this是什么
this是運(yùn)行時(shí)進(jìn)行綁定的,并不是在編寫時(shí)綁定,它的上下文取決于函數(shù)調(diào)用的各種條件。this的綁定和函數(shù)聲明的位置沒有任何關(guān)系,只取決于函數(shù)的調(diào)用方式。this的綁定規(guī)則 默認(rèn)綁定當(dāng)一個(gè)函數(shù)被調(diào)用時(shí),會(huì)創(chuàng)建一個(gè)活動(dòng)記錄(也稱執(zhí)行上下文)。
this既不指向函數(shù)本身,也不指向函數(shù)的詞法作用域。
function foo(){ console.log(this.a); } var a=2; foo();//2
本例中函數(shù)調(diào)用時(shí)應(yīng)用了this的默認(rèn)綁定,因?yàn)閒oo()是直接使用不帶任何修飾的函數(shù)引用進(jìn)行調(diào)用的,因此this指向全局對(duì)象。
*:如果使用嚴(yán)格模式,則不能將全局對(duì)象用于默認(rèn)綁定,因此this會(huì)綁定到undefined。
**:對(duì)于默認(rèn)綁定來(lái)說,決定this綁定對(duì)象的并不是調(diào)用位置是否處于嚴(yán)格模式,而是函數(shù)體是否處于嚴(yán)格模式。
function foo(){ console.log(this.a); } var obj={ a:2, foo:foo }; obj.foo();//2
當(dāng)foo()被調(diào)用時(shí),它的前面確確實(shí)實(shí)加上了對(duì)obj的引用。當(dāng)函數(shù)引用有上下文對(duì)象時(shí),隱式綁定規(guī)則會(huì)把函數(shù)調(diào)用中的this綁定到這個(gè)上下文對(duì)象。因此調(diào)用foo()時(shí)this被綁定到obj,因此this.a和obj.a是一樣的。
對(duì)象屬性引用鏈中只有上一層或者說最后一層在調(diào)用位置中起作用。
function foo(){ console.log(this.a); } var obj={ a:2, foo:foo }; var bar=obj.foo; var a=3; bar();//3
雖然bar是obj.foo的一個(gè)引用,實(shí)際上,它引用的是foo函數(shù)本身,因此此時(shí)的bar()其實(shí)是一個(gè)不帶任何修飾的函數(shù)調(diào)用,因此應(yīng)用了默認(rèn)綁定。
同樣,傳人回調(diào)函數(shù)時(shí)也會(huì)發(fā)生隱式丟失,不管傳入的是自己聲明的函數(shù)還是傳入語(yǔ)言內(nèi)置的函數(shù)。
顯式綁定function foo(){ consol.log(this.a); } var obj={ a:2 }; foo.call(obj);//2
通過foo.call(),我們?cè)谡{(diào)用foo()時(shí)強(qiáng)制把它的this綁定到obj上。
*:從this綁定的角度來(lái)看,call()和apply()是一樣的。
function foo(){ console.log(this.a); } var obj={ a:2 }; var bar=function(){ foo.call(obj); }; bar();//2 setTimeout(bar,100);//2 bar.call(window);//2
本例中我們創(chuàng)建了bar(),并在內(nèi)部手動(dòng)調(diào)用了foo.call(obj),強(qiáng)制把foo的this綁定到了obj。無(wú)論之后怎樣調(diào)用bar,它都會(huì)手動(dòng)在obj上調(diào)用foo。這是一種顯示的強(qiáng)制綁定,稱為硬綁定。
由于硬綁定是一種非常常用的模式,ES5內(nèi)置了bind()方法。其會(huì)返回一個(gè)新函數(shù),把你指定的參數(shù)設(shè)置為this的上下文并調(diào)用原始函數(shù)。
function foo(el){ console.log(el,this.id); } var obj={ id="awesome" }; //調(diào)用 foo()的時(shí)候把this綁定到obj [1,2,3].forEach(foo,obj); //1 awesome 2 awesome 3 awesomenew綁定
關(guān)于new,有一個(gè)重要的點(diǎn):實(shí)際上并不存在所謂的“構(gòu)造函數(shù)”,只有對(duì)于函數(shù)的“構(gòu)造調(diào)用”。
使用new來(lái)調(diào)用函數(shù),或者說發(fā)生構(gòu)造函數(shù)調(diào)用時(shí),會(huì)執(zhí)行下列操作:
(1):創(chuàng)建一個(gè)全新的對(duì)象
(2):這個(gè)新對(duì)象會(huì)被執(zhí)行[[Prototype]]連接
(3):這個(gè)新對(duì)象會(huì)綁定到函數(shù)調(diào)用的this
(4):如果函數(shù)沒有返回其他對(duì)象,那么new表達(dá)式中的函數(shù)會(huì)自動(dòng)返回這個(gè)新對(duì)象
function foo(a){ this.a=a; } var bar=new foo(2); console.log(bar.a);//2
使用new來(lái)調(diào)用foo()時(shí),我們會(huì)構(gòu)造一個(gè)新對(duì)象并把它綁定到foo()調(diào)用的this上。
優(yōu)先級(jí)判斷this:
函數(shù)是否在new中調(diào)用(new綁定)?如果是的話,this綁定的是新創(chuàng)建的對(duì)象
var bar=new foo();
函數(shù)是否通過call、apply(顯式綁定)或者硬綁定調(diào)用?如果是的話,this綁定的是指定的對(duì)象
var bar=foo.call(obj2);
函數(shù)是否在某個(gè)上下文對(duì)象中調(diào)用(隱式綁定)?如果是的話,this綁定到的是那個(gè)上下文對(duì)象
var var=obj1.foo();
如果都不是的話,使用默認(rèn)綁定。如果在于按個(gè)模式下,就綁定到undefined,否則綁定到全局對(duì)象
var bar =foo();綁定例外 被忽略的this
如果你把null或者undefined作為this的綁定對(duì)象傳入call、apply或者bind,這些值在調(diào)用時(shí)會(huì)被忽略,實(shí)際應(yīng)用的是默認(rèn)綁定規(guī)則。
function foo(a,b){ console.log("a:"+a+",","b:"+b); } //把數(shù)組展開成參數(shù) foo.apply(null,[2,3]);//a:2,b:3 //使用bind()進(jìn)行柯里化 var bar=foo.bind(null,2); bar(3);//a:2,b:3
一種更安全的做法是把this綁定到一個(gè)特殊的對(duì)象,且不會(huì)對(duì)程序造成任何副作用??梢允褂靡粋€(gè)DMZ對(duì)象,比如"xx"=Object.create(null)以保護(hù)全局變量。間接引用
間接引用最容易在賦值時(shí)發(fā)生:
function foo(){ console.log(this.a); } var a=2; var o={ a:3, foo:foo }; var p={ a:4 }; o.foo();//3 (p.foo=o.foo)();//2————p.foo=o.foo的返回值是目標(biāo)函數(shù)的引用,因此調(diào)用位置是foo()而不是p.foo()或o.foo(),這里應(yīng)用的是默認(rèn)綁定軟綁定
function foo(){ console.log("name"+this.name); } var obj={ name:"obj"}; var obj1={ name:"obj1"}; var obj2={ name:"obj2"}; var fooOBJ=foo.softBind(obj); fooOBJ();//obj obj2.foo=foo.softBind(obj); obj2.foo();//obj2 fooOBJ.call(obj3);//obj3 setTimeout(obj.foo,10);//objthis詞法
function fo(){ return (a)=>{ console.log(this.a); }; } var obj1={a:1}; var obj2={a:2}; var bar=foo.call(obj1); bar.call(obj2);//1
foo()內(nèi)部創(chuàng)建的箭頭函數(shù)會(huì)捕獲到調(diào)用foo()的this,由于foo()的this綁定到obj1,bar的this也會(huì)綁定到obj1,箭頭函數(shù)的綁定無(wú)法被修改!
具體來(lái)說,箭頭函數(shù)會(huì)繼承外層函數(shù)調(diào)用的this綁定。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/95911.html
摘要:但是如果非全局的變量如果被遮蔽了,無(wú)論如何都無(wú)法被訪問到。但是如果引擎在代碼中找到,就會(huì)完全不做任何優(yōu)化。結(jié)構(gòu)的分句中具有塊級(jí)作用域。第四章提升編譯器函數(shù)聲明會(huì)被提升,而函數(shù)表達(dá)式不會(huì)被提升。 本書屬于基礎(chǔ)類書籍,會(huì)有比較多的基礎(chǔ)知識(shí),所以這里僅記錄平常不怎么容易注意到的知識(shí)點(diǎn),不會(huì)全記,供大家和自己翻閱; 上中下三本的讀書筆記: 《你不知道的JavaScript》 (上) 讀書筆記...
摘要:綁定使用來(lái)調(diào)用函數(shù),或者說發(fā)生構(gòu)造函數(shù)調(diào)用時(shí),會(huì)自動(dòng)執(zhí)行下面的操作。 1 this的概念 this 在任何情況下都不指向函數(shù)的詞法作用域。作用域?qū)ο鬅o(wú)法通過 JavaScript代碼訪問,它存在于 JavaScript 引擎內(nèi)部。 this 是在運(yùn)行時(shí)進(jìn)行綁定的,并不是在編寫時(shí)綁定,它的上下文取決于函數(shù)調(diào)用時(shí)的各種條件。this 的綁定和函數(shù)聲明的位置沒有任何關(guān)系,只取決于函數(shù)的調(diào)用方...
摘要:然而,臨近規(guī)范發(fā)布時(shí),有建議提及未來(lái)的版本號(hào)切換為編年制,比如用同來(lái)指代在年末前被定稿的所有版本??偟脕?lái)說就是版本號(hào)不再那么重要了,開始變得更像一個(gè)萬(wàn)古長(zhǎng)青的活標(biāo)準(zhǔn)。 你不知道的JS(下卷)ES6與之未來(lái) 第一章:ES的今與明 在你想深入這本書之前,你應(yīng)該對(duì)(在讀此書時(shí))JavaScript的最近標(biāo)準(zhǔn)掌握熟練,也就是ES5(專業(yè)來(lái)說是ES 5.1)。在此,我們決定全方面地談?wù)撽P(guān)于將近的...
摘要:綁定書中提到在中,實(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綁...
摘要:強(qiáng)制類型轉(zhuǎn)換本章介紹了的數(shù)據(jù)類型之間的轉(zhuǎn)換即強(qiáng)制類型轉(zhuǎn)換包括顯式和隱式。強(qiáng)制類型轉(zhuǎn)換常常為人詬病但實(shí)際上很多時(shí)候它們是非常有用的。隱式強(qiáng)制類型轉(zhuǎn)換則沒有那么明顯是其他操作的副作用。在處理強(qiáng)制類型轉(zhuǎn)換的時(shí)候要十分小心尤其是隱式強(qiáng)制類型轉(zhuǎn)換。 前言 《你不知道的 javascript》是一個(gè)前端學(xué)習(xí)必讀的系列,讓不求甚解的JavaScript開發(fā)者迎難而上,深入語(yǔ)言內(nèi)部,弄清楚JavaSc...
閱讀 3043·2023-04-26 01:32
閱讀 1640·2021-09-13 10:37
閱讀 2378·2019-08-30 15:56
閱讀 1759·2019-08-30 14:00
閱讀 3195·2019-08-30 12:44
閱讀 2032·2019-08-26 12:20
閱讀 1259·2019-08-23 16:29
閱讀 3308·2019-08-23 14:44