Javascript有兩種開(kāi)發(fā)模式: 1.面向過(guò)程隔显, 2.面向?qū)ο笙罟怼2徽撌敲嫦蜻^(guò)程還是面向過(guò)程侦厚,他們都是一種思維方式耻陕。
面向過(guò)程著重強(qiáng)調(diào)的是,在處理問(wèn)題過(guò)程中刨沦,側(cè)重于如何逐步實(shí)現(xiàn)達(dá)到效果诗宣;
然而在面向?qū)ο笾校枰獦?shù)立兩個(gè)重要的概念:類(lèi)的概念想诅、對(duì)象的概念召庞。類(lèi)的概念即是一種抽象的概念,對(duì)象則是實(shí)際的案例来破。通過(guò)類(lèi)可以創(chuàng)建任意多個(gè)具有相同屬性和方法的對(duì)象篮灼。
面向?qū)ο笳Z(yǔ)言的特性:
1.封裝;
2.繼承徘禁;
3.多態(tài)诅诱。
javascript中獲得對(duì)象的方法
方法有三種,分別是:
1.通過(guò) new Object 得到晌坤;
2.通過(guò)創(chuàng)建Json得到逢艘;
3.通過(guò)構(gòu)造函數(shù)得到。
在以上三種方法中骤菠,第一種使用new Object的獲取它改,因?yàn)椴](méi)有引入類(lèi)的概念,所以如果定義有多個(gè)對(duì)象的時(shí)候商乎,需要進(jìn)行重復(fù)的定義央拖;同樣的,使用Json獲取對(duì)象也存在不能重用對(duì)象的問(wèn)題;那么就使用構(gòu)造函數(shù)的方法既能夠解決對(duì)象重用的問(wèn)題鲜戒,也加入了“類(lèi)”的概念专控,能夠使用instanceof進(jìn)行類(lèi)的判斷(不適用typeOf(),因?yàn)槠渲荒軝z測(cè)出Object())遏餐。
原型
原型即是javascript中一個(gè)特殊的對(duì)象伦腐,當(dāng)函數(shù)對(duì)象創(chuàng)建的時(shí)候,隨之產(chǎn)生一個(gè)原型對(duì)象失都。若是通過(guò)該函數(shù)的構(gòu)造函數(shù)創(chuàng)建了一個(gè)具體的對(duì)象之后柏蘑,在這個(gè)具體的函數(shù)對(duì)象中,會(huì)出現(xiàn)一個(gè)屬性粹庞,該屬性指向原型咳焚。
(針對(duì)于產(chǎn)生的該屬性類(lèi)似于指針,指向原型庞溜。但是在js中并沒(méi)有指針這個(gè)概念革半,所以在此引用“指針”只是為了方便理解)
原型的內(nèi)存模式有以下幾個(gè)步驟:
Step1:
定義function Ball(){}之后,內(nèi)存中創(chuàng)建了一個(gè)Ball對(duì)象流码,隨之產(chǎn)生一個(gè)prototype屬性又官,指向了Ball對(duì)象的原型對(duì)象,而原型對(duì)象中存在了一個(gè)constractor的屬性旅掂,指向Ball對(duì)象赏胚。
Step2:
要在Ball.prototype.name = football,進(jìn)行賦值之后商虐,這些屬性和方法都賦在了Ball對(duì)象的原型對(duì)象上觉阅。
Step3:
根據(jù)Ball構(gòu)造函數(shù)創(chuàng)建一個(gè)對(duì)象b1之后,該對(duì)象中存在了一個(gè)prop的屬性秘车,也指向了Ball對(duì)象的原型對(duì)象典勇,當(dāng)我們調(diào)用該對(duì)象的屬性和方法的時(shí)候,首先在自己的內(nèi)容中尋找叮趴,若是找不到割笙,就去Ball對(duì)象的原型對(duì)象中尋找。
Step4:
當(dāng)創(chuàng)建了一個(gè)新的對(duì)象b2時(shí)眯亦,那么在b2中同樣存在了一個(gè)prop的屬性指向Ball對(duì)象的原型對(duì)象伤溉。如果b2的屬性和方法重新賦值的話,當(dāng)我們調(diào)用時(shí)妻率,會(huì)調(diào)用到我們賦的值乱顾,同樣的,首先在自己的內(nèi)容中尋找宫静,若是找不到走净,就去Ball對(duì)象的原型對(duì)象中尋找券时。(在此過(guò)程中,原型中的屬性和方法不會(huì)被覆蓋)
常見(jiàn)的原型檢測(cè)方式
可以通過(guò)如下的方式檢測(cè)b1是不是指向Ball的原型對(duì)象
alert(Ball.prototype.isPrototypeOf(b1))
//檢測(cè)b1的構(gòu)造器是否指向Ball對(duì)象
alert(b1.constructor == Ball)
//檢測(cè)某個(gè)屬性是不是自己內(nèi)存中的
alert(b1.hasOwnProperty("name"));
alert(b2.hasOwnProperty("name"))
可以使用delete語(yǔ)句刪除對(duì)象中自己的屬性伏伯,那么就會(huì)找到原型中的值
delete b2.name;
b2.say();
alert(b2.hasOwnProperty("name"));
檢測(cè)在某個(gè)對(duì)象自己或者對(duì)應(yīng)的原型中是否存在某個(gè)屬性橘洞。
alert("name" in b1);//true
delete b2.name;//雖然刪除了自己的name屬性,但是原型中有
alert("name" in b2);//true
//原型和自己中都沒(méi)有size屬性
alert("size" in b1);//false
原型重寫(xiě)
為了解決大量的 [對(duì)象.prototype.屬性名 ] 的書(shū)寫(xiě)問(wèn)題说搅,可以使用json的方法進(jìn)行:
function Ball() {
}
Ball.prototype = {
name : "football",
color : "black&white",
say : function() {
alert("my name is: "+this.name+",my color is"+this.color);
}
}
var b1 = new Ball();
b1.say()
var b2 = new Ball();
b2.name = "張三";
b2.color = blue;
b2.say();
function Ball() {
}
Ball.prototype = {
constructor:Ball, //手動(dòng)指向原型對(duì)象
name : "basketball",
age : brown,
say : function() {
alert("my name is : "+this.name+",my color is"+this.age);
}
}
var b1 = new Ball();
b1.say()
var b2 = new Ball();
b2.name = "baseball";
1.封裝
因?yàn)樵痛嬖谡ㄔ妫覀儗?shí)現(xiàn)了對(duì)象的封裝,但是這種封裝也同樣可能存在問(wèn)題的蜓堕。
1抛虏、 我們無(wú)法像使用構(gòu)造函數(shù)的那樣將屬性傳遞用于設(shè)置值
2、 當(dāng)屬性中有引用類(lèi)型套才, 可能存在變量值的重復(fù)
為了解決原型所帶來(lái)的問(wèn)題,需要通過(guò)組合構(gòu)造函數(shù)和原型來(lái)實(shí)現(xiàn)對(duì)象的創(chuàng)建:屬性在構(gòu)造函數(shù)中定義慕淡,方法在原型中定義背伴。這種有效集合了兩者的優(yōu)點(diǎn),是目前最為常用的一種方式峰髓。