少俠俭尖, JS基礎(chǔ)知識產(chǎn)生的蝴蝶效應(yīng)能有多大?~

image

少俠們好~

又是一段時間沒見了洞翩,新的一年了稽犁,希望各位少俠最近過得都還好。

上次和大家說到了對象組合中的 mixin 和 forward骚亿,

本來按道理這次應(yīng)該繼續(xù)對象組合的話題聊下去缭付,

但是!

由于接下來的內(nèi)容會稍微更復(fù)雜一些循未,

同時我想著有些少俠出于某些奇怪的原因,根基可能不太穩(wěn)秫舌。

再加上上次結(jié)尾說了讓你們別猜的妖,猜不到的,有些人應(yīng)該不信足陨!

所以嫂粟,這次的內(nèi)容中的 JS 知識可能是次要的,更重要的是和大家分享一些小思想和經(jīng)驗墨缘,

畢竟某個具體的 JS 知識點(diǎn)可能只能幫助少俠你解決某個 JS 問題星虹,而一些通用的小套路可能會在多個領(lǐng)域?qū)δ阌袔椭?/p>

從標(biāo)題少俠你應(yīng)該也知道了,這次我們的內(nèi)容會和一些基礎(chǔ)知識有關(guān)镊讼,一些你可能都不會怎么放在心上的內(nèi)容宽涌,但是,如果你輕易的忽視它們蝶棋,在關(guān)鍵時刻卸亮,它們卻會對你產(chǎn)生蝴蝶效應(yīng)般的作用,而你甚至都意識不到這一點(diǎn)玩裙。

所以兼贸,這次的內(nèi)容可以算是一半技術(shù)文章段直,更重要的是思想~

tip:這篇文章是接著上一篇文章寫的,最好是按順序看過來的比較好溶诞。

上一篇鏈接:

少俠鸯檬,prototype前傳,了解一下螺垢?


回到起點(diǎn)喧务,深入理解簡單事物

一般來說,不管做什么甩苛,深入理解簡單基礎(chǔ)的事物都是很重要的蹂楣。

只有深入理解了基礎(chǔ)事物,才能更好的應(yīng)對在此這上更復(fù)雜的情況讯蒲。

所以這里我們就聊一點(diǎn)容易被忽視的基礎(chǔ)知識痊土,

在 JS 中也一樣,總有一些最基礎(chǔ)必不可少的東西墨林。

這里我們要聊到的是赁酝。

什么是值呢?

可以看做是 JS 中的最基礎(chǔ)的元素旭等,就像我們世界中的基礎(chǔ)元素酌呆,氫元素,氧元素等等搔耕,

而在 JS 世界中隙袁,這些元素就是字符串,數(shù)字弃榨,布爾值等等菩收。

image

除此之外,還有一些稍微復(fù)雜一些的元素鲸睛,

比如對象娜饵,數(shù)組,以及函數(shù)等等官辈。

image

知道了值之后箱舞,另外一個和它息息相關(guān)的內(nèi)容是表達(dá)式

什么是表達(dá)式呢拳亿? 簡單來說晴股,能夠直接轉(zhuǎn)化成值的東西,就叫做表達(dá)式肺魁。

記住了队魏,少俠,表達(dá)式可以直接轉(zhuǎn)化變成一個值,但是它并不是一個值胡桨。

image

這次的內(nèi)容很簡單吧官帘?

沒錯,都是基礎(chǔ)知識昧谊,我們接著來看另外一個內(nèi)容刽虹,賦值

這個時候可能會稍微有趣一些了呢诬,因為賦值雖然比較簡單涌哲,但是正因為它比較簡單,反而會讓少俠你很容易就忽略掉一些重要的東西尚镰。

你可以給一個變量賦值:

image

給一個對象屬性賦值:

image

還可以給一個數(shù)組賦值:

image

那么問題來了阀圾,

少俠你有沒有想過,當(dāng)你給一個變量狗唉,或者對象屬性賦值時初烘, 你到底是在往里面放什么東西,

或者說分俯,你應(yīng)該在右邊放什么東西肾筐?

當(dāng)然是一個了對吧? 你不可以說缸剪,我在變量里面放一個運(yùn)算符吗铐,比如 + 號。

image

你也不能直接放各種語句杏节,至少在 JS 里面不能:

image

你可以放的只有值:

image

But! 生活總會有意外情況~

有時候唬渗,右邊會是一個表達(dá)式。

image

奋渔?镊逝?? 右邊變成了一個表達(dá)式卒稳,是不是意味著我們剛才說的右邊只能是一個值的規(guī)則不適用了呢?

不是他巨! 記住了充坑,少俠,賦值賦值染突,所以右邊必須得是一個值捻爷。

之所以表達(dá)式也可以放在右邊,是因為表達(dá)式可以變成一個值份企,所以我們可以先解析它也榄,獲取到一個值,然后放進(jìn)去:

image

“為什么可以在右邊放一個表達(dá)式呢?”

“因為表達(dá)式可以變成一個值甜紫!”

“為什么表達(dá)式可以變成一個值呢降宅?”

“因為可以變成值的東西就是表達(dá)式!”

“為什么囚霸。腰根。⊥匦停”

“哪有那么多為什么额嘿!”

所以,少俠你可以在右邊放置任何表達(dá)式劣挫,但是册养,最終,它們都會轉(zhuǎn)成一個值压固。

不管這個值是數(shù)字球拦,字符串,還是函數(shù)邓夕,只要轉(zhuǎn)換出一個可用的值刘莹,就可以了。

Ok~ 再重復(fù)一遍焚刚,如果右邊是一個表達(dá)式点弯,它會先轉(zhuǎn)換成一個值,而且矿咕,重點(diǎn)是它會到此為止抢肛!

“真啰嗦,這么基礎(chǔ)的東西碳柱,還說這么大一堆捡絮!”

“是啊是啊,還重復(fù)說莲镣!”

沒錯福稳! 為什么要重復(fù)說這個基礎(chǔ)的東西呢?

因為它會產(chǎn)生蝴蝶效應(yīng)瑞侮,

還記得上節(jié)最后提到的問題嗎的圆?

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

也就是下面這樣的情況:

image

從上一節(jié)的內(nèi)容中半火,少俠你應(yīng)該知道越妈,第一種方式的話,屬于 early-bound钮糖,而第二種方式梅掠,屬于late-bound。

一個大的區(qū)別就是我們在過后改變了 obj2.fn 的函數(shù)后,一個會更新阎抒,另一個不會酪我。

第一種方式:

image

第二種方式:

image

造成這種差異的原因就是賦值規(guī)則導(dǎo)致的:

第一種賦值情況:

image

這里右邊是什么呢? 右邊是 obj2.fn

第二種賦值情況:

image

這里右邊是什么呢挠蛉? 右邊是 () => obj2.fn();

重點(diǎn)來了祭示! obj2.fn 是一個表達(dá)式! 而 () => obj2.fn() 是一個函數(shù)谴古!

我們已經(jīng)提到過质涛,賦值的右邊必須是值,而 obj2.fn 是表達(dá)式掰担,所以我們必須解析它汇陆,直到獲得一個值。

image

而另外一種情況呢带饱?

() => obj2.fn() 是一個函數(shù)毡代,而函數(shù)本身就是一個值,所以我們不需要做任何操作勺疼!

image

我們這里并不會再去關(guān)心函數(shù)內(nèi)部 obj2.fn 是什么情況教寂,因為函數(shù)還沒有觸發(fā),而賦值的話由于外部箭頭函數(shù)已經(jīng)是一個值了执庐,所以到這也就結(jié)束了酪耕。

所以,第一種情況下,賦值結(jié)束后,obj1.fn 和 obj2.fn 沒有任何關(guān)聯(lián)了勋功,

image

每次調(diào)用 obj1.fn,會直接調(diào)用這個函數(shù)盟步。

而第二種情況則會和 obj2.fn 有關(guān)聯(lián):

image

每次調(diào)用 obj1.fn 時,進(jìn)入到箭頭函數(shù)內(nèi)部躏结,都會重新查找一遍 obj2.fn却盘,并調(diào)用它。

很神奇吧媳拴?

現(xiàn)在少俠你知道為什么obj1.fn = obj2.fn 會立刻查找 obj2.fn 的值了吧黄橘,因為 賦值操作右邊必須是值,而 obj2.fn 不是禀挫,所以會先解析它旬陡,直到獲取到一個可用的值拓颓。

而 obj1.fn = () => obj2.fn(); 由于右邊就是一個函數(shù)语婴,函數(shù)本身就是一個值了,所以會到此為止,并不會再去關(guān)心函數(shù)內(nèi)部什么情況砰左。

造成這樣差距的匿醒,就是和一個小小的賦值運(yùn)算有關(guān)。

“有時候缠导,讓你陷入麻煩的并不是你不知道的事廉羔,而是那些你自以為了解,但實(shí)際上卻是錯誤的事僻造”锼————馬克吐溫”

直覺與規(guī)則,應(yīng)該相信哪一個髓削?

這里另外一個有趣的地方就是函數(shù)必須是惰性的竹挡,這樣我們才可以利用一個中間的箭頭函數(shù)實(shí)現(xiàn) late-bound obj2.fn。

惰性的意思也就是說立膛,函數(shù)內(nèi)部的事情揪罕,必須要在它被調(diào)用時候,才產(chǎn)生效果宝泵。

你不調(diào)用它的時候好啰,就什么也不會發(fā)生。

即使它內(nèi)部可能很危險:

image

這個其實(shí)挺合理的儿奶,盡量只加載必要的內(nèi)容框往,在需要時候再去查找相關(guān)的內(nèi)容,肯定比每次一開始就將所有內(nèi)容全部加載要好很多廓握。

所以搅窿,就算你在函數(shù)內(nèi)部引用了一大堆變量,也只會在調(diào)用它時才開始查找:

image

甚至你函數(shù)內(nèi)部引用了未定義的變量隙券,只要你不觸發(fā)它男应,也不會報錯:

image

理所當(dāng)然的,既然是在函數(shù)調(diào)用時才開始查找對應(yīng)的元素娱仔,那么如果元素中途發(fā)生了改變沐飘,也應(yīng)該以最后一次為準(zhǔn),對吧牲迫?

image

舉個更貼近現(xiàn)實(shí)的例子耐朴,

image

如果一個妹子和你只是普通朋友關(guān)系,直接親可能臉都要被打腫盹憎,但是如果先想辦法追到手筛峭,變成女朋友了,情況可能就不一樣了陪每。

當(dāng)然影晓,這里還是順便說一下如果有普通朋友關(guān)系也可以親的妹子請聯(lián)系我镰吵!

“。挂签。疤祭。?饵婆?勺馆?”

“一天都弄些什么亂七八糟的例子!G群恕草穆!”

好了,現(xiàn)在我們回頭看的話搓译,下面這樣的情況少俠你應(yīng)該就很好理解了:

image

OK续挟,現(xiàn)在,少俠你知道了賦值的規(guī)則侥衬,知道了函數(shù)是惰性的诗祸,知道了如果函數(shù)中引用了一個變量,在函數(shù)調(diào)用時才會去查找轴总,也知道了應(yīng)該以這個變量最后調(diào)用時的值為準(zhǔn)直颅,balabala。怀樟。功偿。

按照道理來說,少俠你應(yīng)該已經(jīng)能夠處理相關(guān)的問題了往堡,

但是~

少俠你的直覺有時候會欺騙你

image

這里調(diào)用兩次函數(shù)的結(jié)果是什么呢械荷?

如果少俠你認(rèn)為是 0 和 1 的話,就說明在 JS 規(guī)則和你的直覺之間虑灰,你相信了后者吨瞎。

正確答案是 2 2。

如果少俠你真的按照我們所說的JS規(guī)則穆咐,一步一步分析的話颤诀,結(jié)果應(yīng)該是下面這樣:

image

而認(rèn)為結(jié)果是0 和 1 的原因是少俠你的大腦忽略了 JS 世界中的規(guī)則,轉(zhuǎn)而采用了更快更輕松的直覺感受对湃,你的直覺會發(fā)現(xiàn)每次遍歷時 i 是 0 和 1崖叫,它會自然的認(rèn)為函數(shù)里的 i 每次也是 0 和 1。

這是你大腦第一反應(yīng)的規(guī)則:

image

但事實(shí)上拍柒,是函數(shù)里面的 i 和遍歷時的 i 沒有關(guān)系心傀,因為函數(shù)是惰性的,它里面的 i 要等到調(diào)用時才開始查找拆讯。

image

跟隨大腦的想法

好了脂男,經(jīng)過上面的內(nèi)容恐锦,少俠你應(yīng)該知道了規(guī)則和直覺有時候會產(chǎn)生沖突,

大腦的第一直覺不一定總是可靠疆液。

不過,

大腦雖然會犯錯陕贮,但是它也有很多好處堕油,

比如如果不是它知道如何控制你用嘴巴吃飯,你可能會餓死肮之!

另外一個好處就是它也喜歡觀察并總結(jié)發(fā)現(xiàn)的事物規(guī)律掉缺,

大腦經(jīng)常也會很好奇,可能會產(chǎn)生一些奇怪的腦洞戈擒,有時候眶明,跟隨大腦的想法,也能夠幫助你發(fā)現(xiàn)新大陸筐高。

比如搜囱,我們上面的函數(shù)都沒有使用到 this,

如果你碰巧又才學(xué)習(xí)了 this柑土,

你的大腦可能會想蜀肘,如果將 this 考慮進(jìn)來,會發(fā)生什么事呢稽屏?

這里我們結(jié)合上一節(jié)的內(nèi)容看看扮宠,

第一種情況:

image

第二種情況:

image

很熟悉的內(nèi)容,因為這就是我們上一次提到的 mixin 和 forward 的情況狐榔。

由于上一節(jié)已經(jīng)詳細(xì)說過這些內(nèi)容了坛增,所以這里就簡單說下結(jié)果,

第一種情況調(diào)用 obj1.fn 會打印出 obj1 中的 name薄腻,'天辰dreamer'收捣。

而第二種情況調(diào)用 obj1.fn 會打印 obj2 中的 name,也就是 '烏云dreamer'庵楷,

而且由于我們的箭頭函數(shù)是惰性的原因坏晦,第二種情況可以在中途改變 obj2.fn 的內(nèi)容,obj1.fn 會自動更新嫁乘。

image

還記得我們上一次的表格嗎昆婿?

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

如果少俠你仔細(xì)觀察的話,你可能會想挎春,

obj1.fn = obj2.fn 中看疙,它是 early-bound豆拨,同時方法中的 this 作用于 obj1

obj1.fn = () => { obj2.fn() } 中能庆,它是 late-bound, 同時方法中的 this 會指向 obj2施禾。

是不是好像缺了兩種情況?

比如能不能實(shí)現(xiàn) early-bound搁胆,而 this 作用于 obj2弥搞,

或者實(shí)現(xiàn) late-bound, this 卻作用于 obj1 上呢?

image

哈哈哈哈哈哈~

沒想到吧渠旁!又繞回來了攀例!

劇情居然突然變得陡峭了起來,基礎(chǔ)不穩(wěn)的少俠有沒有躲在一旁瑟瑟發(fā)抖顾腊?是不是有點(diǎn)措手不及粤铭?

“。杂靶。梆惯。。吗垮。加袋。。抱既。职烧。》辣茫”

image

好了蚀之,嚴(yán)肅臉!

不是故意花里胡哨捷泞,這些內(nèi)容是我認(rèn)為少俠你應(yīng)該理解的足删,理解它們對你熟練掌握J(rèn)S很有幫助,同時能避免很多日乘遥坑失受,也對我們接下來要遇見的 prototype 有很大幫助。

如果你覺得沒用的話咏瑟,我不要你覺得拂到,我要我覺得

那么码泞,最后兩種情況到底能不能實(shí)現(xiàn)呢兄旬?

“當(dāng)然可以了,不可以的話余寥,天辰你提它們干嘛领铐?”

“我隨便說一說不行嘛悯森?”

“騙誰呢,肯定可以绪撵∑耙觯”

“那我這里說它不可以∫粽”

“不可以算了幻碱,反正我們也沒興趣「耐В”

“少俠你怎么能說放棄就放棄呢? 再試一試坟岔≮诵郑”

“不試!”

“我糾正一下剛說過的話社付,是可以實(shí)現(xiàn)的承疲。”

“沒興趣了鸥咖⊙喔耄”

“不會很難的√淅保”

“就不試啊研!”

“。鸥拧。党远。。富弦。沟娱。”

天辰突然和自己內(nèi)心幻想出來的角色吵了起來腕柜,一時生氣直接跑走了济似,臨走前扔下了一張皺巴巴的小紙條。盏缤。砰蠢。

1、函數(shù)是惰性的唉铜,所有放在函數(shù)內(nèi)部的變量娩脾,都會在該函數(shù)調(diào)用時才開始查找,所以 early-bound 和 late-bound 的關(guān)鍵區(qū)別可能是元素放置在函數(shù)內(nèi)外的不同打毛。

image

2柿赊、你可以通過將普通函數(shù)放置在不同對象上調(diào)用來改變其中的 this 指向俩功,你需要 this 指向 a, 你就放在 a 上調(diào)用,你需要 this 指向 b, 你就放在 b 上調(diào)用碰声。

image

3诡蜓、重新回顧一下我們最開始提到的很基礎(chǔ)的規(guī)則可能會有幫助。

4胰挑、少俠蔓罚,江湖路遠(yuǎn),有緣再見~


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

1瞻颂、感覺更新有點(diǎn)慢豺谈,天辰你能不能更新快一點(diǎn)?

不好弄贡这,要有靈感了才能寫茬末,而且如果我自己讀著都比較尷尬的話就不好意思發(fā)出來,得反復(fù)改很多次才行盖矫。丽惭。。

2辈双、說好的藍(lán)胖dreamer圖片呢责掏?

好了,這就是可愛又聽話的藍(lán)胖dreamer了~

image

你可能會以為藍(lán)胖會是只英短貓湃望,但是我叫它藍(lán)胖的原因只是因為它眼睛是藍(lán)色的很好看换衬,然后它長得又比較胖。证芭。冗疮。

3、這次的文章有點(diǎn)奇怪檩帐,感覺好像你說了一大堆术幔,又感覺好像什么都沒說。

很好湃密,說明我的文章已經(jīng)超出了單純的文章本身诅挑!已經(jīng)有點(diǎn)道的感覺了,只可意會不可言傳~

3泛源、好吧好吧拔妥,那么下一次會有 prototype 嗎?达箍!

為什么要急著遇見什么呢没龙?少俠。

說不定當(dāng)我們真正遇見了 prototype 之后,你反而會開始懷念起現(xiàn)在的時刻呢~

4硬纤、文章結(jié)尾是不是太倉促隨意了解滓?

這還叫倉促隨意?少俠你應(yīng)該是沒有看過更倉促的結(jié)尾方式筝家,比如:


聲明:本文僅限于瀟灑有趣又很酷的天辰dreamer裝逼使用洼裤,轉(zhuǎn)載請注明原作者和出處,商業(yè)轉(zhuǎn)載請聯(lián)系我(如果真有的話)溪王。腮鞍。。

image
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末莹菱,一起剝皮案震驚了整個濱河市移国,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌道伟,老刑警劉巖迹缀,帶你破解...
    沈念sama閱讀 212,383評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異皱卓,居然都是意外死亡裹芝,警方通過查閱死者的電腦和手機(jī)部逮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評論 3 385
  • 文/潘曉璐 我一進(jìn)店門娜汁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人兄朋,你說我怎么就攤上這事掐禁。” “怎么了颅和?”我有些...
    開封第一講書人閱讀 157,852評論 0 348
  • 文/不壞的土叔 我叫張陵傅事,是天一觀的道長。 經(jīng)常有香客問我峡扩,道長蹭越,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,621評論 1 284
  • 正文 為了忘掉前任教届,我火速辦了婚禮响鹃,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘案训。我一直安慰自己买置,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評論 6 386
  • 文/花漫 我一把揭開白布强霎。 她就那樣靜靜地躺著忿项,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上轩触,一...
    開封第一講書人閱讀 49,929評論 1 290
  • 那天寞酿,我揣著相機(jī)與錄音,去河邊找鬼怕膛。 笑死熟嫩,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的褐捻。 我是一名探鬼主播掸茅,決...
    沈念sama閱讀 39,076評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼柠逞!你這毒婦竟也來了昧狮?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,803評論 0 268
  • 序言:老撾萬榮一對情侶失蹤板壮,失蹤者是張志新(化名)和其女友劉穎逗鸣,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體绰精,經(jīng)...
    沈念sama閱讀 44,265評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡撒璧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了笨使。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片卿樱。...
    茶點(diǎn)故事閱讀 38,716評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖硫椰,靈堂內(nèi)的尸體忽然破棺而出繁调,到底是詐尸還是另有隱情,我是刑警寧澤靶草,帶...
    沈念sama閱讀 34,395評論 4 333
  • 正文 年R本政府宣布蹄胰,位于F島的核電站,受9級特大地震影響奕翔,放射性物質(zhì)發(fā)生泄漏裕寨。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評論 3 316
  • 文/蒙蒙 一派继、第九天 我趴在偏房一處隱蔽的房頂上張望宾袜。 院中可真熱鬧,春花似錦互艾、人聲如沸试和。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽阅悍。三九已至好渠,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間节视,已是汗流浹背拳锚。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留寻行,地道東北人霍掺。 一個月前我還...
    沈念sama閱讀 46,488評論 2 361
  • 正文 我出身青樓,卻偏偏與公主長得像拌蜘,于是被迫代替她去往敵國和親杆烁。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評論 2 350

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