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