摘要:上一章我們談了構(gòu)造函數(shù),他的唯一特點(diǎn)就是比較了地址不相同,因?yàn)榇蠹抑酪妙愋褪潜容^的引用。也就是說(shuō)不用在構(gòu)造函數(shù)中定義對(duì)象實(shí)例,而是直接將這些添加到原型當(dāng)中。如果構(gòu)造函數(shù)實(shí)例里面沒(méi)有,就去原型里面查找,如果有就立即返回。
上一章我們談了構(gòu)造函數(shù),他的唯一特點(diǎn)就是比較了地址不相同,因?yàn)榇蠹抑酪妙愋褪潜容^的引用。我們來(lái)談?wù)?strong>原型。
原型
我們每創(chuàng)建一個(gè)函數(shù)都有一個(gè)原型(prototype)屬性,這個(gè)屬性是一個(gè)對(duì)象,他的特點(diǎn)是共享。也就是說(shuō)不用在構(gòu)造函數(shù)中定義對(duì)象實(shí)例,而是直接將這些添加到原型當(dāng)中。
function Create () {} //聲明一個(gè)構(gòu)造函數(shù) Create.prototype.a = "abc"; //在原型中添加屬性 Create.prototype.b = 10; Create.prototype.c = function () { //在原型中添加方法 return this.a + this.b; }; var create = new Create(); alert(create.c()); //返回abc10
我們這次再來(lái)比較一下原型中方法的地址是否一致:
var create = new Create(); var create1 = new Create(); alert(create.c == create1.c); //true
是不是還沒(méi)明白?我們用一張圖來(lái)告訴大家:
這個(gè)__proto__就相當(dāng)于指針,指向了原型對(duì)象的constructor,而constructor就相當(dāng)于將構(gòu)造函數(shù)對(duì)象和原型對(duì)象相關(guān)聯(lián)。
那么我們要用構(gòu)造函數(shù)對(duì)象去給重寫屬性或者方法會(huì)怎么樣呢?
var create = new Create(); create.a = "EFD"; alert(create.a); //返回EFD
真的將原型對(duì)象里面的a給覆蓋了么?并沒(méi)有:
var create1 = new Create(); alert(create.a); //返回abc
原型模式的執(zhí)行過(guò)程:
1.先去查找構(gòu)造函數(shù)里面的屬性和方法 ,如果有就立即返回。
2.如果構(gòu)造函數(shù)實(shí)例里面沒(méi)有,就去原型里面查找,如果有就立即返回。
因?yàn)槲覀冊(cè)跇?gòu)造函數(shù)添加了屬性,所以它會(huì)自動(dòng)去查找,構(gòu)造函數(shù)里面的屬性也就立即返回了!
原型的字面量
在原型中,我們也可以使用字面量的方式去創(chuàng)建,可以讓屬性和方法體現(xiàn)出更好的封裝效果。
function Create(a,b){}; //聲明一個(gè)構(gòu)造函數(shù) Create.prototype = { //字面量方式 a:"abc", b:10, c:function () { return this.a + this.b; } };
不知道大家有沒(méi)有發(fā)現(xiàn),我們用字面量的方式是這樣的:Create.prototype ={};
大家都知道,用一個(gè){}就等同于new Create();這樣,我們就相當(dāng)于新聲明的一個(gè)對(duì)象,我們?cè)蛯?duì)象里面的constructor還會(huì)指向Create么?
var create = new Create(); alert(create.constructor == Create); //false alert(create.constructor == Object); //true
(我們來(lái)解釋一下為什么用create.constructor,因?yàn)槲覀兇蛴onstructor就會(huì)將整個(gè)構(gòu)造函數(shù)打印出來(lái),因?yàn)樯厦嬷v過(guò)它是將構(gòu)造函數(shù)對(duì)象和原型對(duì)象相關(guān)聯(lián)的屬性。)
通過(guò)上面的例子可以看出,它已經(jīng)指向了新的實(shí)例對(duì)象。
constructor的巧妙用法:
我們可以使用constructor來(lái)強(qiáng)制指回原來(lái)的實(shí)例對(duì)象:
function Create(a,b){}; Create.prototype = { constructor:Create, a:"abc", b:10, c:function () { return this.a + this.b; } };
原型對(duì)象的重寫問(wèn)題:
大家都知道,構(gòu)造函數(shù)的屬性和方法重寫是無(wú)傷大雅的,但是原型對(duì)象中可以重寫么?
function Create(a,b){}; Create.prototype = { constructor:Create, a:"abc", b:10, c:function () { return this.a + this.b; } }; Create.prototype = { a:"EFD", }; var create = new Create(); alert(create.c()); //create.c is not a function
不難看出,我們重寫了原型會(huì)將之前的原型指向切斷?。?!
原型模式的缺點(diǎn):
其實(shí)它的缺點(diǎn)也是它優(yōu)點(diǎn):共享。
我們?cè)谧置媪坷锩娼o原型對(duì)象添加一個(gè)數(shù)組就很容易的看出來(lái)了:
function Create(a,b){}; Create.prototype = { constructor:Create, a:"abc", b:10, c:[第一個(gè),第二個(gè),第三個(gè)], d:function () { return this.a + this.b + this.c; } }; var create = new Create(); create.c.push("第四個(gè)"); alert(create.run()); //返回abc10第一個(gè)第二個(gè)第三個(gè)第四個(gè)
我們看得出這時(shí)候push添加已經(jīng)生效了,在數(shù)組的末尾添加了“第四個(gè)”
我們?cè)賮?lái)實(shí)例一個(gè)對(duì)象就能看得出他的共享問(wèn)題了:
var create1 = new Create(); alert(create1.run()); //返回abc10第一個(gè)第二個(gè)第三個(gè)第四個(gè)
這就是共享問(wèn)題。下面新實(shí)例化一個(gè)對(duì)象也會(huì)將上面添加的字符串給共享到這里來(lái)。
這一章就到這里。歡迎所有閱讀文章的人指正錯(cuò)誤!
Brian Lee
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/91136.html
摘要:構(gòu)造函數(shù)通過(guò)原型繼承了構(gòu)造函數(shù)和原型,這就形成了一個(gè)鏈條,通俗的講就是原型鏈繼承。而且方法只能冒充構(gòu)造函數(shù)里面的屬性和方法而無(wú)法冒充原型對(duì)象里面的屬性和方法還有最大的問(wèn)題就是重復(fù)使用。 前言: 寫到這里,差不多就把OOP完結(jié)了,寫了幾篇OOP的文章,但是只是略懂皮毛,可能深入的OOP還有很多,但是我感覺(jué)寫到這里也算是差不多完結(jié)了。 繼承 繼承是面向?qū)ο蟊容^核心的概念,其他語(yǔ)言可能實(shí)現(xiàn)...
摘要:構(gòu)造函數(shù)上一章我們講了工廠模式,它的缺點(diǎn)就是無(wú)法識(shí)別到底哪個(gè)屬于哪個(gè)的問(wèn)題。我們可以用構(gòu)造函數(shù)來(lái)解決這個(gè)識(shí)別問(wèn)題。來(lái)比較構(gòu)造函數(shù)內(nèi)的值就可以看出到底是什么類型。 構(gòu)造函數(shù) 上一章我們講了工廠模式,它的缺點(diǎn)就是無(wú)法識(shí)別到底哪個(gè)屬于哪個(gè)的問(wèn)題。我們可以用構(gòu)造函數(shù)來(lái)解決這個(gè)識(shí)別問(wèn)題。 //構(gòu)造函數(shù) function Create(a,b) { this.a =a; this...
摘要:面向?qū)ο竺嫦驅(qū)ο缶幊痰娜Q是,簡(jiǎn)稱,面向?qū)ο缶幊淌怯贸橄蠓绞絼?chuàng)建基于現(xiàn)實(shí)世界模型的一種編程模式。面向?qū)ο缶幊痰娜齻€(gè)主要特征是封裝繼承多態(tài)。 面向?qū)ο?面向?qū)ο缶幊痰娜Q是Object Oriented Programming,簡(jiǎn)稱OOP,面向?qū)ο缶幊淌怯贸橄蠓绞絼?chuàng)建基于現(xiàn)實(shí)世界模型的一種編程模式。面向?qū)ο缶幊炭梢钥醋鍪鞘褂靡幌盗袑?duì)象相互協(xié)作的軟件設(shè)計(jì),面向?qū)ο蟪绦蛟O(shè)計(jì)的目的是在編程中促...
摘要:注意這里跟原型鏈繼承有個(gè)比較明顯的區(qū)別是并沒(méi)有使用繼承而是在子類里面執(zhí)行父類的構(gòu)造函數(shù)相當(dāng)于把父類的代碼復(fù)制到子類里面執(zhí)行一遍這樣做的另一個(gè)好處就是可以給父類傳參。 Javascript繼承 學(xué)過(guò)后端語(yǔ)言的同學(xué)對(duì)繼承并不陌生,但是對(duì)JS繼承少許還是有些困惑,不要試圖問(wèn)我是如果知道的,其實(shí)javascript繼承主要是基于原型prototype實(shí)現(xiàn)的。 其實(shí)當(dāng)你真正了解了原型鏈時(shí)候,再看...
摘要:工廠模式優(yōu)點(diǎn)集中實(shí)例化,可以傳參等缺點(diǎn)分不清屬于哪個(gè)對(duì)象我們先來(lái)談?wù)剝?yōu)點(diǎn),看例子集中實(shí)例化返回實(shí)例化對(duì)象返回返回不難看出,工廠模式比上面的例子減少了很多代碼。 ECMAscript開(kāi)發(fā)的兩種模式:1.過(guò)程化 2.OOP(面向?qū)ο? 面向?qū)ο蟮恼Z(yǔ)言有一個(gè)標(biāo)志,那就是類的概念,而通過(guò)類可以創(chuàng)建任意多個(gè)具有相同屬性的方法的對(duì)象。但是ECMAscript中沒(méi)有類的概念! 又談作用域 首先...
閱讀 2119·2021-11-23 09:51
閱讀 2283·2021-09-29 09:34
閱讀 3769·2021-09-22 15:50
閱讀 3615·2021-09-22 15:23
閱讀 2723·2019-08-30 15:55
閱讀 761·2019-08-30 15:53
閱讀 3146·2019-08-29 17:09
閱讀 2700·2019-08-29 13:57