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