javascript
JS修仙之一界本源
自計算機(jī)宇宙誕生以來,有很多大神通者在這里開天辟地,開創(chuàng)了很多界,有C、C++、Java等世界,它們彼此相連,其中有一處叫做JavaScript的世界,自被開辟以來吸引了很多修行者來此修煉。JS界由ES、DOM、BOM組成。
話說這一日,齊云道長慕名來到JS界,剛?cè)氪私?#xff0c;便被界中三座大山吸引,分別名曰:作用域閉包、原型鏈繼承、異步。相傳此三山中藏著js界的創(chuàng)世本源。道長便在此閉關(guān),靜心感悟。
時間一晃就是數(shù)月,齊云早已把js界基本情況了解了,不過至于三座大山里隱藏的謎團(tuán)卻遲遲沒有頭緒。苦悶之中,坐在山上看日出日落,觀星辰變化。斗轉(zhuǎn)星移之間,齊云感慨萬物變化奇妙,口中念起了老君的《道德經(jīng)》:道生一,一生二,二生三,三生萬物,萬物負(fù)陰而抱陽。卻突然露出了笑容:“怎么沒早點想到呢,道衍萬物。就是在主宇宙也是生于大道,更何況在這js世界呢”。
相傳當(dāng)年布蘭登十天造此界,應(yīng)該也是按照這個思路來的。萬物都從無產(chǎn)生,此界也是無中生有,0和1是計算機(jī)宇宙中的陰陽,界中萬物都是由此衍化。再定下八卦五行,此界便可運轉(zhuǎn)繁衍不息。以往大部分人都是從基本的語法開始感悟,今天我從null開始推演。
了解宇宙本源之后,齊云此時心中有了明悟,仿佛看到了這個世界被創(chuàng)造和不斷完善的樣子。
>雖然js經(jīng)過幾次的升級,擁有更強(qiáng)大的功能,不過最初js只是用來做簡單的數(shù)據(jù)驗證。。后來在ECMA-262中定義了ES,才提供了核心語言功能。
開天辟地是第一步,這個天地就叫引擎。最早只有創(chuàng)始人布蘭登在網(wǎng)景時開辟的SpiderMonkey,之后諸神又開辟了幾處不同的天地,JScript(IE6,IE7, IE8)、Chakra(IE9,IE10, IE11, IE Edge)、SpiderMonkey(Firefox)、JavaScriptCore(Safari)、V8(Chrome)。不同空間的環(huán)境略有不同,但js子民大多可以在這幾處天地下都能生存,只不過生活節(jié)奏工作效率不一樣(引擎性能不同)。更有平行天地Node等。天地既有了,便可以創(chuàng)造萬物以及定下此界的規(guī)則。萬物由代碼組成,我們不可能一下子把萬物都生成,只需要創(chuàng)造出最基本的元素和種類,之后讓他們衍生萬物。
**組成代碼的五行:變量、操作符、控制語句、對象、函數(shù)。**
變量:不給強(qiáng)制規(guī)定類型,可以說是世界最平等的事了,不管你本身什么類型,它都平等對待你,不過麻煩倒也很多。。
函數(shù):創(chuàng)造了不少默認(rèn)的行為規(guī)則,toString()、get()、set()就好像人會吃飯睡覺的行為一樣,被規(guī)定的。
>這里只是化用五行,僅僅代表最基本的五種元素,并沒有相生相克這些。
基本元素有了,怎么利用這些元素組成無數(shù)的代碼,這些代碼又如何豐富世界呢?只有道衍生的規(guī)則能辦到,就好像四季更迭,花開花落一般。生與死,對與錯。
規(guī)則之一:語法。它規(guī)定了區(qū)分大小寫、標(biāo)識符、注釋、嚴(yán)格模式、操作符、語句、對象的形式、函數(shù)定義。
規(guī)則之二:數(shù)據(jù)類型和數(shù)據(jù)類型的轉(zhuǎn)化,好比水變成冰
規(guī)則之三:作用域,上下文,閉包。它描述變量存儲的規(guī)律,細(xì)看js修仙之作用域閉包一文
規(guī)則之四:原型鏈規(guī)則。它是JS界本源之一。有著名的this規(guī)則
規(guī)則之五:異步規(guī)則。異步操作是為了改善單線程
規(guī)則之等等:。。。還有很多規(guī)則,例如錯誤處理等。詳看ECMAScript標(biāo)準(zhǔn)
**借助八卦,將js中八種事物融合進(jìn)來,相互配合,組成運轉(zhuǎn)的JS界。**
**乾代表引擎,坤代表回收機(jī)制,震代表構(gòu)造函數(shù),巽代表引用類型,坎代表執(zhí)行語句,離代表編譯器,艮代表異步,兌代表同步。**
>乾為天,坤為地,離為太陽,坎為月亮,四卦不停準(zhǔn)轉(zhuǎn)有了event loop,有了代碼生成編譯銷毀,事件處理,好比四季循環(huán)。之后又有了了震雷,雷動生巽風(fēng),雷風(fēng)相薄,構(gòu)造函數(shù)和引用類型互相影響,艮山兌水,同步異步在event loop中在運轉(zhuǎn)。
和其他OO世界一樣,JS也是對象的世界。對象擁有著屬性和方法。屬性就是特征,方法就是行為。有了這些對象就能動起來了,仿佛擁有了生命一樣。我們不可能一下子創(chuàng)造出所有的對象,只有先造出第一批對象,它們是JS對象老祖,負(fù)責(zé)繁衍教化萬民。JS世界對象有自己的特點,它們當(dāng)中有普通對象和函數(shù)對象。函數(shù)對象地位較高,屬于一等公民,它們可以被調(diào)用,還修行一種獨特的法術(shù),叫做原型之體。原型之體與函數(shù)之體通過**prototype和constructor**相連。本體通過prototype可以獲取原型之體的能力,原型之體則通過constructor表明自己函數(shù)之體的身份。
>雖然typeof function a(){}返回的是'function'不是'object',這是因為函數(shù)確實有一些特殊的屬性,因此用typeof來區(qū)分函數(shù)和其他對象是有必要的
>
>有人說JS中萬物皆對象,事實上是錯誤的,因為(string、boolean、number、number、undefined)本身不是對象,而是基本類型如a=2。
在每個對象中都存在一塊印記,叫[[prototype]],它是對象的血脈之力,有著驚人的作用,當(dāng)發(fā)動血脈之力時,可以發(fā)揮先祖之力,甚至可以使出先天對象的法術(shù)。有如此大的威力,主要因為對象的[[prototype]]印記連接的是父輩的原型之體!而父輩之體也有屬于自己的血脈之力,因此后輩對象中有遇到自己解決不了的問題時,血脈之力會觸發(fā),幫助它們渡過難關(guān)。
有一個特殊的對象Object.prototype,它是這個世界所有對象的智慧之祖,所有的對象都繼承了它的智慧。另一個重要的對象是Function.prototyp,它擁有了關(guān)于函數(shù)對象的智慧,并且它也繼承了Object.prototype的智慧。這兩個對象我稱它們?yōu)橄忍鞂ο?#xff0c;是JS根基對象,它們高高在上,是萬象之根。而且它們是Object和Function對象的原型之體,神通廣大,原型之體術(shù)就是它們最先練就。Function掌管著函數(shù)對象,Object掌管著原型之體和普通對象。**幾乎所有的函數(shù)都是引用類型Function的實例,幾乎所有的對象都是Object的實例**Function.prototype繼承了Object.prototype(雖然會出現(xiàn)覆蓋),Object的血脈又連接Function,可以說這兩位是其他JS對象共同的老祖。
```javascript
Function.prototype.__prototype === Object.prototype
Object.__prototype === Function.prototype
```
>在某對象中找不到要找的屬性時,就會沿著原型鏈網(wǎng)上找。從ECMAScript6開始,[[Prototype]]可以通過Object.getPrototypeOf()和Object.setPrototypeOf()訪問器來訪問,這個等同于JS的非標(biāo)準(zhǔn)但許多瀏覽器實現(xiàn)的屬性__proto__
全局的Function對象沒有自己的屬性和方法,繼承于Function.prototype,因此Function.prototype是不能被修改的。Function.prototype還有個特殊的身份,它也是個函數(shù),簡直是深藏不露。
```javascript
console.log(Function.prototype)
[Function]
```
剩下的一些對象組成了長老會,它們分別是Array、Date、RegExp、String、Math、Error等,以及后面加入的Set、Map等幾位長老。長老們擁有各自的神通和家族。例如Array長老擅長操作數(shù)組,有sort、slice等神通,而Math長老有random神通。不過它們也都是Object和Fucntion的部下。每個長老的函數(shù)之體源自Function,繼承了Function.prototype的神通。而它們的原型之體繼承了Object.prototype的智慧。
**對象是引用類型的實例**,通過new加構(gòu)造函數(shù)可以創(chuàng)造新對象,后來先天對象Object又感悟了Object.create之法,也可以創(chuàng)造新的對象。
>事實上,根本沒有構(gòu)造函數(shù),或者人人都是構(gòu)造函數(shù)。當(dāng)且僅當(dāng)使用new時,函數(shù)調(diào)用會變成構(gòu)造函數(shù)調(diào)用。
JS界的老祖,長老會及長老會門下關(guān)系如下:
可以看到兩位老祖高高在上,受萬眾仰視。它們與多位長老一樣,函數(shù)體通過藍(lán)色箭頭prototype指向原型之體。原型之體通過灰色線constructor連接函數(shù)之體,后代子孫而血脈之力由[[prototype]]沿著橙色線,找到了父對象(構(gòu)造函數(shù))的原型之體,父對象或長老們的原型之體的血脈是綠色的線,指向了Object.prototype。
```javascript
duke.__proto__ === Sub.prototype
Sub.prototype.__proto__ = == Object.prototype
-------------------------------------------------
Sub.__proto__ === Function.prototype
Function.prototype.__proto__ === Object.prototype
```
至此,我們可以這么歸納:
1.**所有對象都有隱式原型[[prototype]],它指向了創(chuàng)造它的構(gòu)造函數(shù)的原型對象,一直連接到Object.prototype,而Object.prototype也有隱式原型,而它指向Null**,當(dāng)訪問一個對象的屬性找不到時,會沿原型鏈向上找,找到了會返回,找不到就會繼續(xù)向上知道null會返回undefined。
2.**幾乎所有函數(shù)都是Function的實例,為了符合這個規(guī)則,Function的隱式原型指向的是它的原型對象。**
易是包羅萬象,一切事物和現(xiàn)象都可以裝進(jìn)這個模式里,易是變化的,不管代碼如何復(fù)雜,都是符合最基本的規(guī)則,易雖然變化,但大道是永恒的,變化之道是不變的。JS的世界也是這樣,不管由多復(fù)雜的代碼組成的程序,也都得遵循最基本的變量聲明語法,也要符合原型的設(shè)計模式,也都得按照既定的規(guī)則來編寫。所以,明白這個JS界的一界本源,才能在這里暢游天地之間。
?
轉(zhuǎn)載于:https://www.cnblogs.com/shaotang/p/10281251.html
總結(jié)
- 上一篇: hbase基础建表语句
- 下一篇: 重写,重载,抽象类,接口,抽象类和接口区