成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

再和“面向?qū)ο蟆闭剳賽?- 對象相關(guān)概念(二)

qpwoeiru96 / 592人閱讀

摘要:所有的對象都是由構(gòu)造函數(shù)創(chuàng)建的對象哪來的構(gòu)造函數(shù)生的。而普通函數(shù)不能生成對象不孕不育,構(gòu)造函數(shù)可以生成對象有生育能力。別急,記住那句話永遠指向?qū)嵗龑ο髮?yīng)的構(gòu)造函數(shù)的,那就先看實例對象是誰。

上一篇文章把對象的概念講解了一下,這篇文章要重點解釋最讓大家犯迷糊的一些概念,包括

構(gòu)造函數(shù)

實例

繼承

構(gòu)造函數(shù)的屬性與方法(私有屬性與方法)

實例的屬性與方法(共享屬性與方法)

prototype(原型)

__proto__(原型)

構(gòu)造函數(shù)
構(gòu)造函數(shù)依然是個函數(shù),用來生成對象。所有的對象都是由構(gòu)造函數(shù)創(chuàng)建的

對象哪來的?構(gòu)造函數(shù)生的。而普通函數(shù)不能生成對象(不孕不育),構(gòu)造函數(shù)可以生成對象(有生育能力)。每個對象都會有一個自己對應(yīng)的構(gòu)造函數(shù),但是不代表每個構(gòu)造函數(shù)都會生(生成實例),有不會生的構(gòu)造函數(shù),例如Math對象(不孕不育)

console.dir(Array);     //數(shù)組的構(gòu)造函數(shù)
console.dir(Function); //函數(shù)的構(gòu)造函數(shù)
console.dir(Object);   //對象的構(gòu)造函數(shù)

new Math();     //報錯,不能生成實例
new Window();   //報錯,不能生成實例

唐僧說過一句話,用來解釋構(gòu)造函數(shù)與實例再合適不過了“人是人他媽生的,妖是妖他媽生的”那這里的人他媽與妖他媽就是構(gòu)造函數(shù)。人與妖其實是下面要說的概念“實例”

實例
實例就是對象,由構(gòu)造函數(shù)生成

平時用的實際的東西都是實例(獲取的DOM元素、聲明的數(shù)組、聲明的函數(shù)、聲明的對象),有時候需要new關(guān)鍵字生成(不是絕對的)

實例身上有一個constructor屬性,它指向?qū)?yīng)構(gòu)造函數(shù)(生母)

判斷一個對象是否是某個構(gòu)造函數(shù)的實例,用instanceof運算符

//實例
[];             //不用new生成
new Array();    //用new生成

[].constructor===Array; //true
[] instanceof Array;    //true
繼承
生成的實例具有構(gòu)造函數(shù)身上的屬性與方法(就像老鼠的兒子會打洞)
一個對象身上有另一個對象身上的屬性或方法,這種具有的方式就叫繼承

說到繼承首先想到的就是遺產(chǎn)。老人去世了,在二環(huán)里留了一套四合院,那這套房子歸誰呀?不可能歸我吧,歸我的話我就不用在這吭哧吭哧寫文章了。那也不能歸你吧,歸你了你也不能座這看我吭哧吭哧寫的文章。得歸人家兒子,這個就是繼承。那從這個例子中得出幾個重要信息,繼承者與被繼承者之間是有一定關(guān)系的,最簡單的就是父子或者母子關(guān)系。

那回到程序中,構(gòu)造函數(shù)就是老人,實例就是兒子。那實例的屬性或者方法哪來的?構(gòu)造函數(shù)的,不過它可以繼承過來,這是合理合法的。但是也會有特殊情況,假如老人膝下無子,那這房子怎么辦?充公?不能吧,要你你干么?不過這個老人有一個唯一的親人,就是弟弟。那弟弟能否拿到這個房子呢,應(yīng)該是可以的。再回到程序中,剛才這種情況其實程序中也存在,就是一個對象可以有另一個對象身上的東西。

//arr身上是并沒有push方法,這個方法來自于構(gòu)造函數(shù)Array,是arr繼承了構(gòu)造函數(shù)身上的這個方法
const arr=[1,2];
arr.push(3);
console.log(arr);    //[1, 2, 3]

//Array對象身上并沒有valueOf方法,這個方法來自于Object對象,是Array對象繼承了Object對象的這個方法
Array.valueOf===Object.valueOf;   //true
構(gòu)造函數(shù)的屬性與方法(私有屬性與私有方法)
構(gòu)造函數(shù)身上的屬性與方法,只有構(gòu)造函數(shù)能用,實例不能用

再回到這1個億的例子中來,這個老人為啥有個四合院呢,這位老人原來是個老兵,立過一等功,戰(zhàn)功赫赫,獲得了無數(shù)勛章。那我問你他的這些榮譽,兒子有么?或者弟弟有么?沒有吧。這個就是構(gòu)造函數(shù)特有的屬性與方法,實例身上是沒有的

//構(gòu)造函數(shù)的私有屬性與方法
console.log(Array.name);    //Array
console.log(Array.of(5));    //[5]

//實例不能用
const arr=[];   //實例
console.log(arr.name);        //undefined
arr.of(6);    //報錯
實例的屬性與方法(共享屬性與共享方法)
實例身上的屬性與方法,只有實例能用,構(gòu)造函數(shù)不能用(放在prototype里)

老人有兩個孩子,這倆孩子跟我學(xué)會了js,又學(xué)會了ES6,現(xiàn)在在百度上班做開發(fā),這你說扯不扯,我都快編不下去了。那這些技能老人會么,他不會。所以這個就叫實例的屬性與方法,只能實例去用,構(gòu)造函數(shù)用不了

//實例的方法
const arr=[1,2,3];
console.log(arr.concat(["a","b"]));    //[1, 2, 3, "a", "b"]

Array.concat(["a","b"]));    //報錯。你的就是你的,我的就是我的,不能互用。就跟媳婦是一樣

//但構(gòu)造函數(shù)可以間接用
console.log(Array.prototype.concat(["a","b"]));    //["a", "b"]
prototype(原型)
1、構(gòu)造函數(shù)身上的一個屬性,它的類型為對象,這個屬性的值就是原型
2、這個對象里放的屬性與方法,就是構(gòu)造函數(shù)的共享屬性與共享方法,所有實例都能用

還得回到那一個億的例子里,我們說兒子能繼承老子的遺產(chǎn),為什么呢?因為他有個神器叫戶口本,國家給發(fā)的,能證明他們是父子關(guān)系。你去辦手續(xù)的時候肯定要拿著戶口本。現(xiàn)在都得要證件,當(dāng)然有的時候你可能需要到派出所開個證明,證明你就是你。雖然有點扯哈,但是有真實發(fā)生過,如果派出所不給你證明,那你就不是你。回到程序中,雖然你知道實例是構(gòu)造函數(shù)生的,那實例就能有構(gòu)造函數(shù)身上的方法,為什么呢?其實他們也有證,跟戶口本一樣,這個證就是prototype

//prototype 原型
console.log(Array.prototype);   //數(shù)組的原型對象

//如果把原型上的方法刪除了,那實例就不能用了。證明原型里放的屬性與方法都是實例的屬性與方法
const arr=[];
Array.prototype.push=null;
arr.push(6);    //報錯
__proto__(原型)
1、這個屬性是瀏覽器自己部署的,到了ES6也沒有正式寫入標(biāo)準(zhǔn)里,建議大家不要用它,用Object.getPrototypeOf()方法替代
2、它也是指原型對象,與prototype一樣。但是有區(qū)別:歸屬不同,prototype是函數(shù)身上的屬性,__proto__是對象身上的屬性

這個屬性與prototype屬性往往讓大部分人都百思不得其解,看得是一頭霧水,腦袋擰成了麻花,網(wǎng)上的資料是一堆一堆,但往往大家看得是一愣一愣。其實這倆東西很簡單,是一道推算題,首先,你要明白原型的結(jié)果只有一個,就是構(gòu)造函數(shù)的prototype屬性的值。那為什么瀏覽器看熱鬧不嫌事大,給我們找麻煩,又部署了一個__proto__呢?其實瀏覽器也是好心,但沒成想辦了壞事。在沒有這個屬性以前,只能從函數(shù)身上找到原型。為了能從實例對象身上也能找到原型,瀏覽器就部署了這個屬性。以字符串為例推算如下:

字符串構(gòu)造函數(shù)的原型放在String.prototype里。那現(xiàn)在我能否通過實例找到這個原型呢?也就是str ? ===String.prototype

const str=new String("kaivon");
console.dir(str);    //打印出實例,點開后看到__proto__

要通過實例找到原型的話,首先要通過實例找到構(gòu)造函數(shù)(因為原型在構(gòu)造函數(shù)身上)。前面有說過,實例身上都有一個屬性叫constructor,這個就指向構(gòu)造函數(shù)

console.log(str.constructor===String);    //true 通過實例找到了構(gòu)造函數(shù)

那找到了構(gòu)造函數(shù),原型不就放在構(gòu)造函數(shù)身上么?所以變成了這樣

console.log(str.constructor.prototype===String.prototype);    //true

到這里就推出來如何通過實例找到原型,但是這么寫是不是有點長呢?天空一聲巨響,__proto__閃亮登場,瀏覽器為了簡化操作,就讓__proto__等于constructor.prototype,也就是變成下面這樣

console.log(__proto__===constructor.prototype);    //true

所以整個語句其實就可以變成這樣

console.log(str.__proto__===String.prototype);    //true

到這里就明白了吧,再總結(jié)一下

prototype屬性是構(gòu)造函數(shù)身上的,指向原型

__proto__屬性是對象身上的,指向原型

實例的.__proto__===構(gòu)造函數(shù).prototype

現(xiàn)在是不是恍然大悟、如夢初醒、豁然開朗,但是我不得不澆你一頭冷水啊,還沒有完,看下面

console.dir(String);//打印出構(gòu)造函數(shù),點開也看到了__proto__

剛才不是說這玩意是實例身上的么,現(xiàn)在怎么跑到構(gòu)造函數(shù)身上了?童話里都是騙人的嗎?別急,構(gòu)造函數(shù)是函數(shù)么?函數(shù)是對象么?是吧,這就對了。其實上面的推理題都好說,都簡單。大家弄不懂的是在這。網(wǎng)上的文章就在這里讓你的麻花越擰越緊。構(gòu)造函數(shù)是函數(shù),是函數(shù)它就是對象,__proto__既然是對象身上的,那這個構(gòu)造函數(shù)身上就一定會有。點開__proto__看一下

里面的內(nèi)容不應(yīng)該是String原型的內(nèi)容么?好像不是哎,這就傻逼了,剛搞清楚的東西現(xiàn)在全亂了。別急,記住那句話__proto__永遠指向?qū)嵗龑ο髮?yīng)的構(gòu)造函數(shù)的prototype,那就先看實例對象是誰。我們點開的這個String它是什么?它是構(gòu)造函數(shù),它的類型是個函數(shù)。雖然它是一個構(gòu)造函數(shù),但在這里它就是一個實例對象,并且它的類型是函數(shù),所以它是Function構(gòu)造函數(shù)的實例,那Function的實例對象身上的__proto__不應(yīng)該指向Functionprototype么?所以這里面的內(nèi)容為Function對象的原型

console.log(String.__proto__===Function.prototype);    //true

接著看,這里還有一個__proto__

真是害怕什么來什么呀!這是__proto__來自于Functionprototype,它是個原型對象,原型對象的數(shù)據(jù)類型當(dāng)然為對象了,所以它是Object構(gòu)造函數(shù)的實例,那Object的實例對象身上的__proto__不應(yīng)該指向Objectprototype么,所以點開這個__proto__里面的內(nèi)容是Object.prototype的值

console.log(String.__proto__.__proto__===Object.prototype);    //true

因為Object已經(jīng)是頂層對象了,所以在它的prototype里不會再出現(xiàn)__proto__了,但是有人說Object其實還有繼承,繼承于null。但是我不太認同這種說法,__proto__的值是個對象類型數(shù)據(jù),而Object已經(jīng)是頂層對象了,它原型對象的__proto__肯定沒有值了,在ECMAScriptnull的數(shù)據(jù)類型又為對象,所以就呼應(yīng)上了,而不是繼承于null。

Object.prototype.__proto__===null;  //true

到這里我把面向?qū)ο螽?dāng)中關(guān)鍵的一些概念算是說清楚了,下一篇文章來說一下真正的面向?qū)ο蟾拍睿?/p>

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/96630.html

相關(guān)文章

  • 再和面向對象戀愛 - 圖片預(yù)加載組件(七)

    摘要:源碼下載至此再和面向?qū)ο笳剳賽巯盗形恼乱呀?jīng)全部更新完畢寫文章不易,且行且珍惜 再和面向?qū)ο笳剳賽?- 對象簡介(一)再和面向?qū)ο笳剳賽?- 對象相關(guān)概念(二)再和面向?qū)ο笳剳賽?- 面向?qū)ο缶幊谈拍睿ㄈ┰俸兔嫦驅(qū)ο笳剳賽?- class(四)再和面向?qū)ο笳剳賽?- 繼承(五)再和面向?qū)ο笳剳賽?- super(六) 通過前面的六篇文章已經(jīng)把ES6的面向?qū)ο蟾蠡镎f清楚了,大家最關(guān)心的...

    caoym 評論0 收藏0
  • 再和面向對象戀愛 - 面向對象編程概念(三)

    摘要:說到底面向?qū)ο蟛攀浅绦蛘Z言的根本。其實面向?qū)ο缶幊陶f的就是自定義對象。里并沒有類的概念,所以嚴格上來講這是個假的面向?qū)ο罄锏拿嫦驅(qū)ο缶幊态F(xiàn)在好了,終于聽到別人鄙視我們了,給我們提供了類這個概念,其實是向傳統(tǒng)語言更靠齊了。 通過前兩篇文章,我們了解了對象的概念以及面向?qū)ο罄锏南嚓P(guān)概念等知識,那前面說了對象分類里的前兩種,這篇文章要詳細去說第三種自定義對象,那真正的好戲這就來了! 面向?qū)ο?..

    Cruise_Chan 評論0 收藏0
  • 再和面向對象戀愛 - class(四)

    摘要:在上一篇文章里我介紹了一下面向?qū)ο缶幊痰母拍?,在最后終于喜出望外看到了提供了類的概念了。而到了里面真正的類與構(gòu)造函數(shù)現(xiàn)在是分離的,通過上面的代碼可以看出來,這種寫法正是面向?qū)ο蟮恼y(tǒng)寫法。 在上一篇文章里我介紹了一下面向?qū)ο缶幊痰母拍?,在最后終于喜出望外看到了ES6提供了類的概念了。那這個類如何去用,是這篇文章的主題。ES6給我們提供了一個class關(guān)鍵字。這個關(guān)鍵字跟以前的var l...

    劉東 評論0 收藏0
  • 再和面向對象戀愛 - 繼承(五)

    摘要:面向?qū)ο罄镒畲蟮奶攸c應(yīng)該就屬繼承了。在第二篇文章里說過原型實例跟構(gòu)造函數(shù)之間的繼承,并且還講了一道推算題。 通過上一篇文章想必各位老鐵已經(jīng)熟悉了class了,這篇文章接著介紹繼承。面向?qū)ο罄镒畲蟮奶攸c應(yīng)該就屬繼承了。一個項目可能需要不斷的迭代、完善、升級。那每一次的更新你是要重新寫呢,還是在原有的基礎(chǔ)上改吧改吧呢?當(dāng)然,不是缺心眼的人肯定都會在原來的基礎(chǔ)上改吧改吧,那這個改吧改吧就需要...

    Airmusic 評論0 收藏0
  • 再和面向對象戀愛 - super(六)

    摘要:同時彈出的結(jié)果是指向了子類,又說明雖然調(diào)用的是父類的構(gòu)造函數(shù),但是調(diào)用完后會指向子類,指向也被改成了子類的實例。 在上一篇文章里介紹了繼承,那其中說過一個很關(guān)鍵的東西想要繼承子類里里必需先調(diào)用一個super方法。而super的作用絕對是價值連城!同時super的作用還有多種,并且跟你的使用環(huán)境有關(guān)系。 1、當(dāng)作函數(shù)使用 super被當(dāng)作函數(shù)使用,這種情況是最普遍的,上一篇文章里已經(jīng)使用...

    Towers 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<