java中this的軟綁定

首先框仔,什么是軟綁定舀武?

?所謂軟綁定,是和硬綁定相對應(yīng)的一個詞离斩,在詳細(xì)解釋軟綁定之前银舱,我們先來看看硬綁定。

在JavaScript中跛梗,this的綁定是動態(tài)的寻馏,在函數(shù)被調(diào)用的時候綁定,它指向什么完全取決于函數(shù)在哪里調(diào)用核偿,情況比較復(fù)雜诚欠,光是綁定規(guī)則就有默認(rèn)綁定、隱式綁定漾岳、顯式綁定轰绵、new綁定等,而硬綁定是顯式綁定中的一種尼荆,通常情況下是通過調(diào)用函數(shù)的 apply() 左腔、 call() 或者ES5里提供的 bind() 方法來實現(xiàn)硬綁定的。

硬綁定有什么問題捅儒,為什么需要軟綁定 液样?

上述三個方法好是好振亮,可以按照自己的想法將函數(shù)的this強(qiáng)制綁定到指定的對象上(除了使用new綁定可以改變硬綁定外),但是硬綁定存在一個問題蓄愁,就是會降低函數(shù)的靈活性双炕,并且在硬綁定之后無法再使用隱式綁定或者顯式綁定來修改this的指向。 在這種情況下撮抓,被稱為軟綁定的實現(xiàn)就出現(xiàn)了,也就是說摇锋,通過軟綁定丹拯,我們希望this在默認(rèn)情況下不再指向全局對象(非嚴(yán)格模式)或 undefined (嚴(yán)格模式),而是指向兩者之外的一個對象(這點和硬綁定的效果相同)荸恕,但是同時又保留了隱式綁定和顯式綁定在之后可以修改this指向的能力乖酬。

軟綁定的具體實現(xiàn)

?if(!Function.prototype.softBind)

{

?Function.prototype.softBind=function(obj)

{?

?var fn=this;?

?var args=Array.prototype.slice.call(arguments,1);?

?var bound=function()

{?

?return fn.apply(

(!this||this===(window||global))?obj:this,? args.concat.apply(args,arguments) );? };?

?bound.prototype=Object.create(fn.prototype);?

?return bound;

};

}

我們先來看一下效果,之后再討論它的實現(xiàn)融求。

學(xué)習(xí)群64弍46衣3凌9咬像,資料群69似64陸0吧3

?function foo(){? console.log("name: "+this.name); }

var obj1={name:"obj1"}, obj2={name:"obj2"},? obj3={name:"obj3"};

var fooOBJ=foo.softBind(obj1); fooOBJ();//"name: obj1" 在這里軟綁定生效了,成功修改了this的指向生宛,將this綁定到了obj1上

obj2.foo=foo.softBind(obj1);??obj2.foo();//"name: obj2" 在這里軟綁定的this指向成功被隱式綁定修改了县昂,綁定到了obj2上

fooOBJ.call(obj3);//"name: obj3" 在這里軟綁定的this指向成功被硬綁定修改了,綁定到了obj3上

setTimeout(obj2.foo,1000);//"name: obj1"

/*回調(diào)函數(shù)相當(dāng)于一個隱式的傳參陷舅,如果沒有軟綁定的話倒彰,這里將會應(yīng)用默認(rèn)綁定將this綁定到全局環(huán)? 境上,但有軟綁定莱睁,這里this還是指向obj1*/

可以看到軟綁定生效了待讳。下面我們來具體看一下 softBind() 的實現(xiàn)。

在第一行仰剿,先通過判斷创淡,如果函數(shù)的原型上沒有 softBind() 這個方法,則添加它南吮,然后通過 Array.prototype.slice.call(arguments,1) 獲取傳入的外部參數(shù)琳彩,這里這樣做其實為了函數(shù)柯里化,也就是說旨袒,允許在軟綁定的時候汁针,事先設(shè)置好一些參數(shù),在調(diào)用函數(shù)的時候再傳入另一些參數(shù)(關(guān)于函數(shù)柯里化大家可以去網(wǎng)上搜一下詳細(xì)的講解)最后返回一個 bound 函數(shù)形成一個閉包砚尽,這時候施无,在函數(shù)調(diào)用 softBind() 之后,得到的就是 bound 函數(shù)必孤,例如上面的 var fooOBJ=foo.softBind(obj1) 猾骡。 在 bound 函數(shù)中瑞躺,首先會判斷調(diào)用軟綁定之后的函數(shù)(如fooOBJ)的調(diào)用位置,或者說它的this的指向兴想,如果 !this (this指向undefined)或者 this===(window||global) (this指向全局對象)幢哨,那么就將函數(shù)的this綁定到傳入 softBind 中的參數(shù)obj上。如果此時this不指向undefind或者全局對象嫂便,那么就將this綁定到現(xiàn)在正在指向的函數(shù)(即隱式綁定或顯式綁定)捞镰。

?fn.apply 的第二個參數(shù)則是運行 foo 所需要的參數(shù),由上面的args(外部參數(shù))和內(nèi)部的arguments(內(nèi)部參數(shù))連接成毙替,也就是上面說的柯里化岸售。 其實在第一遍看這個函數(shù)時,也有點迷厂画,有一些疑問凸丸,比如 var fn=this 這句,在 foo 通過 foo.softBind() 調(diào)用 softBind 的時候袱院,fn到底指向誰呢屎慢?是指向foo還是指向softBind?我們可以寫個demo測試忽洛,然后可以很清晰地看出fn指向什么:

var a=2;?

?function foo(){ }?

?foo.a=3;

Function.prototype.softBind=function()

{? var fn=this;??return function(){ console.log(fn.a); } };

Function.prototype.a=4;?

?Function.prototype.softBind.a=5;

foo.softBind()();//3

Function.prototype.softBind()();//4

可以看出腻惠,fn(或者說this)的指向還是遵循this的綁定規(guī)則的, softBind 函數(shù)定義在Function的原型 Function.prototype 中脐瑰,但是JavaScript中函數(shù)永遠(yuǎn)不會“屬于”某個對象(不像其他語言如java中類里面定義的方法那樣)妖枚,只是對象內(nèi)部引用了這個函數(shù),所以在通過下面兩種方式調(diào)用時苍在,fn(或者說this)分別隱式綁定到了 foo 和 Function.prototype 绝页,所以分別輸出3和4。后面的 fn.apply() 也就相當(dāng)于 foo.apply() 寂恬。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末续誉,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子初肉,更是在濱河造成了極大的恐慌酷鸦,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件牙咏,死亡現(xiàn)場離奇詭異臼隔,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)妄壶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進(jìn)店門摔握,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人丁寄,你說我怎么就攤上這事氨淌〔蠢ⅲ” “怎么了?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵盛正,是天一觀的道長删咱。 經(jīng)常有香客問我,道長豪筝,這世上最難降的妖魔是什么痰滋? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮续崖,結(jié)果婚禮上即寡,老公的妹妹穿的比我還像新娘。我一直安慰自己袜刷,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布莺丑。 她就那樣靜靜地躺著著蟹,像睡著了一般。 火紅的嫁衣襯著肌膚如雪梢莽。 梳的紋絲不亂的頭發(fā)上萧豆,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天,我揣著相機(jī)與錄音昏名,去河邊找鬼涮雷。 笑死,一個胖子當(dāng)著我的面吹牛轻局,可吹牛的內(nèi)容都是我干的洪鸭。 我是一名探鬼主播,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼仑扑,長吁一口氣:“原來是場噩夢啊……” “哼览爵!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起镇饮,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤蜓竹,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后储藐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體俱济,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年钙勃,在試婚紗的時候發(fā)現(xiàn)自己被綠了蛛碌。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡肺缕,死狀恐怖左医,靈堂內(nèi)的尸體忽然破棺而出授帕,到底是詐尸還是另有隱情,我是刑警寧澤浮梢,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布跛十,位于F島的核電站,受9級特大地震影響秕硝,放射性物質(zhì)發(fā)生泄漏芥映。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一远豺、第九天 我趴在偏房一處隱蔽的房頂上張望奈偏。 院中可真熱鬧,春花似錦躯护、人聲如沸惊来。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽裁蚁。三九已至,卻和暖如春继准,著一層夾襖步出監(jiān)牢的瞬間枉证,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工移必, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留室谚,地道東北人。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓崔泵,卻偏偏與公主長得像秒赤,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子管削,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,055評論 2 355

推薦閱讀更多精彩內(nèi)容