少俠爆存,prototype前傳蛉顽,了解一下?

image

少俠們好先较,

上次和大家聊了一些關(guān)于this的故事携冤,在最后,我們也說了闲勺,還有一些相關(guān)的內(nèi)容和問題沒有談到曾棕,

比如,prototype原型鏈菜循,

不管是在你閱讀文章翘地,還是面試時,可能都會被問到關(guān)于它的問題癌幕。

如果少俠你看過關(guān)于它的文章衙耕,

你很可能已經(jīng)見過一些和它相關(guān)的字眼,prototype勺远,_proto_橙喘,new,this 等等胶逢。

但是厅瞎,即使你對這些字眼都很熟悉了,你可能也會有一個疑惑宪塔,

原型鏈到底是什么磁奖? 到底是怎么來的,又有什么作用呢某筐?

為了弄清楚它比搭,在這次的故事中,我們會先講述一些關(guān)于對象其他的內(nèi)容,這些內(nèi)容能夠幫我們最終過渡到原型鏈去身诺,并真正了解它做了什么蜜托。

它們可能與原型鏈無關(guān),但是以后卻能夠幫助你更好的理解原型鏈霉赡。

這就是為什么我們的標題會是

prototype前傳

好了橄务,下面開始進入正題~


冰山之下

少俠,如果你看過上一節(jié)關(guān)于 this 的故事的話穴亏,你應(yīng)該已經(jīng)知道蜂挪,之所以會有 this 存在,其實就是因為我們需要有這樣一個動態(tài)的東西嗓化。

用來干嘛呢棠涮? 用來做對象組合,這樣我們就可以復用和組合現(xiàn)成的對象刺覆,來完成新的功能严肪。

了解事物的本質(zhì)這一點非常非常重要,

比如你知道了 this 出現(xiàn)的原因就是為了動態(tài)組合對象谦屑,所以它會動態(tài)的變來變?nèi)ヒ簿筒黄婀至恕?/p>

原型鏈也是一樣驳糯,理解它的關(guān)鍵點就在于弄清楚它的本質(zhì)是什么,實際上氢橙,它的本質(zhì)和 new 沒有什么必然的關(guān)系酝枢,和所謂的_proto_ 也沒有太大的關(guān)系,

它的本質(zhì)是對象組合充蓝。

我們可以有多種方式來組合對象隧枫,組合方式的不同,就構(gòu)成了一個個不同的方法谓苟,

原型鏈就是其中之一官脓,

除了它之外,也還有很多其他的方式涝焙,

所以今天卑笨,我們先不說原型鏈,說一說其他的組合方式~

首先仑撞,來看看我們上次的一個例子:

image

在這里赤兴,我們有一個 user 對象,里面包含了 user 的名稱隧哮,寵物列表桶良,以及兩個對應(yīng)的方法,一個用來獲取名稱沮翔,另一個用來添加寵物陨帆。

這種對象,大多數(shù)情況是沒有什么問題的,你可以很方便的把相關(guān)的邏輯放在一起來使用,

不過疲牵,這種方式承二,有時候也會不太容易復用和組合,

因為它只是很簡單的把數(shù)據(jù)和行為混合在了一起纲爸,會顯得有點 too young too simple,

所以亥鸠,我們來試著把數(shù)據(jù)和行為單獨放在不同的對象里。

image

分開很簡單识啦,不過负蚊,光分開是沒有用的,在合適的時候颓哮,我們得想辦法把它們再組合起來才行盖桥,因為光有數(shù)據(jù)的話,就好比少俠你有一大筆錢题翻,卻找不到花錢的地方,而光有行為的話腰鬼,就好比少俠你可以花錢如流水嵌赠,但是,賬上沒有流水熄赡。姜挺。。

所以彼硫,它們得組合在一起才能完全發(fā)揮出作用炊豪。

怎么組合呢?

第一種組合的方式拧篮,在上節(jié)關(guān)于 this 的故事中词渤,少俠你其實已經(jīng)遇見過了,就是我們在使用 Object.assign 時的方式串绩,它也叫做 mixin缺虐。

Mixin

Mixin 是最簡單的合并對象的方式,通過將一個對象中的屬性復制到另外一個對象中來實現(xiàn)合并礁凡。

image

在這里高氮,我們通過自定義的 mixin 函數(shù)把 userActions 里面的方法混入到了 user 中。

當然顷牌,使用內(nèi)置的 Object.assign 可能會好一些:

image

少俠你可以看到剪芍,通過 mixin , 我們的 user 對象獲得了 userActions 中的方法。

mixin 的好處是你可以把 userActions 同時混入多個對象窟蓝,來達到方法復用的效果罪裹。

image

mixin 的方式有幾個特點,

第一個特點是 mixin 處理對象的方式屬于 early-bound

什么意思呢? 意思是結(jié)果對象中的方法在經(jīng)過 mixin 處理時就已經(jīng)確定了坊谁,即使你會過后才調(diào)用它费彼,但是它是在 mixin 那一刻就已經(jīng)確定了。

比如這里我們將 userActions 混入到 user 中口芍,user 中的 getName 或是 addPets只會取決于混入這一刻時 userActions 中的對應(yīng)方法箍铲,混入完成后,即使我們過后改變 userActions 中 getName 方法鬓椭,對 user 也不會有任何影響颠猴。

image

這就是 early-bound,也就是說小染,會調(diào)用哪個函數(shù)翘瓮,在一開始的時刻就已經(jīng)確定好了,所以是 early裤翩。

第二個特點是通過 mixin 處理的對象资盅,最終所有的效果都會在我們的接收者上發(fā)生。

比如踊赠,我們把 userActions 混入到 user 之后呵扛,user 就是接收者,當我們調(diào)用 user.getName 方法時筐带,它會去查找 user 上的 name今穿,不會對 userActions 造成任何影響,只和它本身有關(guān)伦籍,就算你把 userActions 銷毀了蓝晒,設(shè)置為 null,也沒關(guān)系帖鸦。

“天辰芝薇,這不是廢話嗎?我都把方法放在它里面了富蓄,也已經(jīng)混入完成了剩燥,調(diào)用時不和它有關(guān),難道還和你有關(guān)立倍?”

“對啊灭红,這不很明顯嘛?有什么好說的口注”淝埽”

沒錯,這里是很明顯寝志,也是 mixin 的特點娇斑,

但是策添,在另外的組合方式下,情況可能就完全不一樣了毫缆!

比如接下來我們要說的 forward 方式唯竹。

Forward

另外一種對象組合的方式是 forward,它和我們的 mixin 區(qū)別有點大苦丁,因為浸颓,它既不是 early-bound,作用的效果也不是在接收者上旺拉。

我們接著上面的例子來看吧产上,想象少俠你已經(jīng)通過 mixin 把 userActions 混入到 user 中了,

然后蛾狗,現(xiàn)在我們遇見了新情況晋涣,一個寵物店,它可以讓我們捐獻寵物沉桌,

假設(shè)這是我們的寵物店對象:

image

如果你想給寵物店捐獻寵物的話谢鹊,

如何將我們的 user 對象和寵物店關(guān)聯(lián)起來呢?

這種情況留凭,少俠你不能使用 mixin(user, petStore)的方式撇贺,

除非。冰抢。。少俠你想把自己變成一個寵物店艘狭。挎扰。。

image

這時巢音,我們就需要另外一種組合方式遵倦,

也就是 forward !

它可以讓我們將另一個對象上的方法組合進來官撼,并且當你調(diào)用這些方法時梧躺,它會在原來的對象上發(fā)揮作用。

類似這樣:

image

那么 forward 長什么樣呢傲绣?

見證奇跡的時刻掠哥!

image

我們來試試用 forward 把 petStore 整合進來:

image

好了,少俠應(yīng)該已經(jīng)發(fā)現(xiàn) forward 的區(qū)別了秃诵,在這里续搀,我們希望 userActions 中的方法作用于 user 本身,于是我們采用mixin菠净,

但是我們卻希望 petStore 上的方法作用于 petStore 本身禁舷,只不過可以在 user 上調(diào)用彪杉,我們則采用了 forward。

所以我們可以使用 user.addPet 給 user 內(nèi)部的 pets 添加寵物牵咙,然后使用 user.givePet 給 petStore 內(nèi)部的 pets 添加寵物派近。

很神奇是吧?

我們還可以把多個用戶和同一個寵物店關(guān)聯(lián)起來:

image

在這里洁桌,我們通過 forward 函數(shù)渴丸,同時把 petStore 關(guān)聯(lián)到了兩個不同的用戶上,

然后战坤,user1 和 user2 會共享同一個 petStore曙强,也就是,你通過 user 添加一個寵物途茫,再通過 user2 添加一個寵物碟嘴,petStore 上會有2個寵物,這些數(shù)據(jù)針對所有用戶都是同步的囊卜。

“哦娜扇,這樣啊,那么共享的數(shù)據(jù)有什么用處呢栅组?”

“對雀瓢,我又不開寵物店,換個另外的例子玉掸!”

具體的用途的話刃麸,不同的少俠會有不同的理解,就像它本身體現(xiàn)的特點一樣司浪,如果有一些數(shù)據(jù)你想在多個不同的對象之間共享泊业,也許你就可以試試這種方式。

當然啊易,天辰我人比較好吁伺,

所以這里我就再給少俠你舉個簡單例子了,比如你頁面自定義了一個路由棧:

image

很明顯的是租谈,路由對于所有的頁面應(yīng)該是共享的篮奄,不管哪個頁面返回了一級,對于的路由棧就應(yīng)該減少一層割去,所以我們使用了 forward 來將路由方法共享到每個頁面中窟却。

early-bound 與 late-bound

上面我們提到過, mixin 是 early-bound呻逆,意思是间校,一旦混入了一些方法,就算我們過后改變了源對象中的方法页慷,也不會對已經(jīng)混入后的對象有所影響憔足。

那么 late-bound 又是什么意思呢胁附?

繼續(xù)我們的 forward 旅程,在之前滓彰,我們已經(jīng)和寵物店建立了合作關(guān)系:

image

但是控妻!現(xiàn)在由于天辰捐贈的小貓 藍胖dreamer 過于調(diào)皮,所以揭绑,寵物店決定暫時不接受繼續(xù)捐贈叫做藍胖的小貓了弓候。

image

好了,現(xiàn)在寵物店更新了新規(guī)則他匪,那么我們之前 forward 的方法還有用嗎菇存? 是需要我們手動再 forward 一次,還是會自動更新呢邦蜜?

我們來試一試

image

很神奇依鸥!

我們并不需要重新進行 forward ,當我們改變了 petStore 中的方法時悼沈,對應(yīng) user 中的方法會自動更新贱迟!這點和 mixin 不一樣,如果是 mixin 的話絮供,我們必須重新 mixin 一次才有效衣吠。

為什么會這樣呢?

原因是 forward 中下面這段代碼:

image

這里的關(guān)鍵點在于壤靶,我們并沒有直接把 petStore.givePet 賦值給 user缚俏,而是利用了一個中間的箭頭函數(shù)。

這樣的話贮乳,在一開始袍榆,user.givePet 只是和這個箭頭函數(shù)聯(lián)系了起來,它并不會馬上就繼續(xù)去查看箭頭函數(shù)里面的內(nèi)容,畢竟箭頭函數(shù)都還沒有調(diào)用對吧宿崭?

也就是說亲铡,到我們真正調(diào)用這個箭頭函數(shù),并開始查找其中的 petStore.givePet 之間的時間段葡兑,我們是可以改變 petStore.givePet 方法的奖蔓。

在這之間,不管中途 givePet 變換了多少次讹堤,就算它有一段時間變成 undefined吆鹤,null 等等也沒有關(guān)系,因為只要我們不觸發(fā)箭頭函數(shù)洲守,它就不會去查找 petStore.givePet疑务。

它過去是什么不重要沾凄,重要的是,我們找到它時知允,它是什么撒蟀。

汝未看此花時,此花與汝同歸于寂温鸽。汝來看此花時保屯,此花顏色一時明白過來。便知此花不在汝之心外涤垫」贸撸——王陽明

好了,這就是 early-bound 和 late-bound 的區(qū)別了蝠猬,一個是在最開始就決定好調(diào)用哪個函數(shù)了切蟋,另一個則是在調(diào)用時,才開始查找調(diào)用哪個函數(shù)吱雏。

總結(jié)一下~

組合方式 bound 類型 方法中的作用對象 數(shù)據(jù)是否獨立
mixin early-bound 對象本身 是敦姻,每個對象的操作不會影響其他 mixin 對象
forward late-bound 用于組合的對象 否,用于所有對象會共享 forward 進來的對象數(shù)據(jù)歧杏,所以會互相影響

完全OK!

恭喜你镰惦,少俠~

你又成功發(fā)現(xiàn)并閱讀完了一篇非常有趣的文章!

希望能夠?qū)δ阌兴斋@~

可惜的是犬绒,我們依然還沒有說到 prototype 旺入,

而且你可能也還有一些疑問,

沒有關(guān)系凯力,

以后還會有很多有趣的內(nèi)容會提到的茵瘾,

如果少俠你覺得以上內(nèi)容對你有幫助的話,

希望可以幫忙給分享或點個贊咐鹤,

讓我感受一下江湖的溫暖~

好了拗秘,江湖路遠,少俠我們有緣再見~

一些你可能關(guān)心的問題

1祈惶、等了這么久的prototype原型鏈胸私,結(jié)果天辰你告訴我還有前傳恒削?

別急民晒,少俠些己,前傳通常能夠幫助你更好的了解劇情,這里也是一樣疹蛉,相信我活箕,這樣的路線也許能夠幫你更好的過渡到原型鏈,而且可款,說不定我們一不小心就實現(xiàn)它了育韩,還順帶解鎖一堆隱藏的小伙伴呢~

2克蚂、好吧,老實說座慰,forward 的實現(xiàn)有點沒看懂陨舱。。版仔。

哈哈哈哈游盲,我就知道(突然出現(xiàn)的迷之優(yōu)越感),少俠你可以這樣對比 mixin 和 forward:

image

我們上面的 forward 函數(shù)只不過多了自動檢測 obj2 中的方法蛮粮,并批量賦值這么一個過程益缎。

真正的關(guān)鍵點,就是一個多了一個中間箭頭函數(shù)然想,另外一個沒有莺奔。

注意了,少俠! 請你認真仔細的觀察它們的區(qū)別变泄,多測試一下令哟,找找不同點~

3、為什么 obj1.fn = () => { obj2.fn(); } 會在箭頭函數(shù)調(diào)用時再去查找 obj2.fn妨蛹,而直接賦值 obj1.fn = obj2.fn 卻不在調(diào)用 obj1.fn 時再去查找 obj2 中的 fn 呢

我就知道有人可能會有這個疑問屏富!

這個問題實際上和 JS 中的賦值運算有關(guān)。

本來打算就這里說了蛙卤,不過發(fā)現(xiàn)內(nèi)容稍微有點長狠半,就下次出單獨的專題說!

少俠你可以先自行思考下颤难,或者查找一下網(wǎng)上的資源神年,留給你當做練習題。

tip: 可以再參考一下上個問題中的流程行嗤。

4已日、接下來是不是要開始說關(guān)于prototype原型鏈的故事了?

不知道! 生活總是會給你帶來驚喜栅屏,我也是飘千!不能隨便透露下面的內(nèi)容,甚至下一次說的還是不是 JavaScript 都不一定既琴,所以,別亂猜了泡嘴,少俠甫恩,直接點贊關(guān)注加轉(zhuǎn)發(fā)~

5、藍胖dreamer 是個什么鬼酌予? 真的是只調(diào)皮的寵物嗎磺箕?

當然是真的寵物奖慌,不過,現(xiàn)實中的它一點也不調(diào)皮松靡!反而很聽話~

下一篇文章爭取給它爆個照简僧!

6、干嘛要在名稱后面加個 dreamer 雕欺?

之前以為 dreamer 的意思是幻想家岛马,像是形容那些懷揣夢想的人,感覺很酷屠列,但是后來知道了它的意思其實也有不切實際的人啦逆,看起來很奇怪, 既有褒義又有貶義笛洛,后來我想了下夏志,也許 dreamer 在一開始本身就是不好不壞的,與其在一開始去糾結(jié)它的意思苛让,倒不如選擇成為一個 dreamer沟蔑,親自去定義它。

Be a dreamer, not a loser. 少俠~


聲明:本文僅限于瀟灑有趣又很酷的天辰dreamer裝逼使用狱杰,轉(zhuǎn)載請注明原作者和出處瘦材,商業(yè)轉(zhuǎn)載請聯(lián)系我(如果真有的話)。浦旱。宇色。

image
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市颁湖,隨后出現(xiàn)的幾起案子宣蠕,更是在濱河造成了極大的恐慌,老刑警劉巖甥捺,帶你破解...
    沈念sama閱讀 212,718評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件抢蚀,死亡現(xiàn)場離奇詭異,居然都是意外死亡镰禾,警方通過查閱死者的電腦和手機皿曲,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來吴侦,“玉大人屋休,你說我怎么就攤上這事”溉停” “怎么了劫樟?”我有些...
    開封第一講書人閱讀 158,207評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我叠艳,道長奶陈,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,755評論 1 284
  • 正文 為了忘掉前任附较,我火速辦了婚禮吃粒,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘拒课。我一直安慰自己徐勃,他們只是感情好,可當我...
    茶點故事閱讀 65,862評論 6 386
  • 文/花漫 我一把揭開白布捕发。 她就那樣靜靜地躺著疏旨,像睡著了一般。 火紅的嫁衣襯著肌膚如雪扎酷。 梳的紋絲不亂的頭發(fā)上檐涝,一...
    開封第一講書人閱讀 50,050評論 1 291
  • 那天,我揣著相機與錄音法挨,去河邊找鬼谁榜。 笑死,一個胖子當著我的面吹牛凡纳,可吹牛的內(nèi)容都是我干的窃植。 我是一名探鬼主播,決...
    沈念sama閱讀 39,136評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼荐糜,長吁一口氣:“原來是場噩夢啊……” “哼巷怜!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起暴氏,我...
    開封第一講書人閱讀 37,882評論 0 268
  • 序言:老撾萬榮一對情侶失蹤延塑,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后答渔,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體关带,經(jīng)...
    沈念sama閱讀 44,330評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,651評論 2 327
  • 正文 我和宋清朗相戀三年沼撕,在試婚紗的時候發(fā)現(xiàn)自己被綠了宋雏。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,789評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡务豺,死狀恐怖磨总,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情笼沥,我是刑警寧澤蚪燕,帶...
    沈念sama閱讀 34,477評論 4 333
  • 正文 年R本政府宣布招狸,位于F島的核電站,受9級特大地震影響邻薯,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜乘凸,卻給世界環(huán)境...
    茶點故事閱讀 40,135評論 3 317
  • 文/蒙蒙 一厕诡、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧营勤,春花似錦灵嫌、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至赂蠢,卻和暖如春绪穆,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背虱岂。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評論 1 267
  • 我被黑心中介騙來泰國打工玖院, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人第岖。 一個月前我還...
    沈念sama閱讀 46,598評論 2 362
  • 正文 我出身青樓难菌,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蔑滓。 傳聞我的和親對象是個殘疾皇子郊酒,可洞房花燭夜當晚...
    茶點故事閱讀 43,697評論 2 351

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