面向?qū)ο蟮乃枷胫饕且詫ο鬄橹髁淠瑢⒁粋€問題抽象出具體的對象,并且將抽象出的對象和對象的屬性和方法封裝成一個類汤功。
面向過程就是分析出解決問題所需要的步驟物邑,然后用函數(shù)把這些步驟一步一步實(shí)現(xiàn),使用時候依次調(diào)用函數(shù)滔金。
面向?qū)ο笫前褬?gòu)成問題事務(wù)分解成各個對象色解,建立對象的目的不是為了完成一個步驟而是為了描述某個事物在整個解決問題的步驟中的行為
面向?qū)ο笏枷氲奶攸c(diǎn)
1.封裝
對于同一個功能,只需要封裝一次餐茵,以后再使用科阎,只需要調(diào)用即可,無需重寫忿族,即低耦合高內(nèi)聚锣笨。
2.繼承
子類可以繼承父類的屬性和方法
3.多態(tài):重載和重寫
重載:js中沒有真正意義上的重載蝌矛,但有類似重載的功能,就是傳不同的參數(shù)错英,有不同的返回值入撒;
重寫:子類可以重寫父類的屬性和方法。
創(chuàng)建對象
1.工廠模式
這種模式抽象了具體對象的過程椭岩,此方法是用函數(shù)來封裝以特定接口創(chuàng)建對象的細(xì)節(jié)
function createPerson(name,age,sex) {
var obj = new Object();
obj.name = name;
obj.age = age;
obj.sex = sex;
obj.sayName = function () {
alert(this.name)
}
return obj
}
var person1 = createPerson('james',18,'male');
var person2 = createPerson('curry',20,'male')
函數(shù)createPerson()能夠根據(jù)接收的參數(shù)來構(gòu)建一個包含所有必要信息的person對象茅逮。可以多次調(diào)用這個函數(shù)判哥,每次都返回含有三個屬性一個方法的對象献雅。
缺點(diǎn)是無法確定創(chuàng)建對象的類型。應(yīng)為都是Object姨伟,沒有區(qū)分度惩琉,不能像Date,Array一樣夺荒。
2.構(gòu)造函數(shù)模式
javascript中有像Object和Array一樣的原生構(gòu)造函數(shù)瞒渠,除此之外,我們?yōu)槟梢詣?chuàng)建自定義的構(gòu)造函數(shù)技扼,從而自定義對象的屬性和方法伍玖。
構(gòu)造函數(shù)的命名采用大駝峰式命名
function Person(name,age,sex) {
this.name = name;
this.age = age;
this.sex = sex;
this.sayName = function (){
alert(this.name)
}
}
var person1 = new Person('james',18,'male');
var person2 = new Person('curry',20,'male')
要創(chuàng)建Person的實(shí)例,必須使用new操作符剿吻,以這種方式調(diào)用構(gòu)造函數(shù)會經(jīng)歷以下三個步驟:
(1)創(chuàng)建一個this對象
var this = {}
(2)將構(gòu)造函數(shù)的作用域賦值給新對象并執(zhí)行構(gòu)造函數(shù)中那個的代碼
this = { name : name, age : age, sex : sex, sayName : function () {alert(this.name)} }
(3)返回新對象
return this
構(gòu)造函數(shù)方法的主要問題是每個方法都要在每個實(shí)例上重新創(chuàng)建一遍窍箍,person1和person2都有sayName()的方法,但兩個方法不是同一個Functon的實(shí)例丽旅。說明白些椰棘,以這種方式創(chuàng)建函數(shù),會導(dǎo)致不同的作用域鏈和標(biāo)識符解析榄笙,但創(chuàng)建Function新實(shí)例的機(jī)制是相同的邪狞,因此不同實(shí)例上的同名函數(shù)是不相等的,如下:
console.log(person1.sayname == person2.sayName) //false
3.原型模式
我們創(chuàng)建的每個函數(shù)都有一個prototype屬性茅撞,prototype是通過調(diào)用構(gòu)造函數(shù)創(chuàng)建的實(shí)例的原型對象帆卓。使用原型對象可以讓所有對象實(shí)例共享它所包含的屬性和方法。
function Person() {}
Person.prototype.name = 'james';
Person.prototype.age = 18;
Person.prototype.sex = 'male'
Person.prototype.sayName = function () {
alert(this.name)
}
var person1 = new Person();
person1.sayName() //'james'
var person2 = new Person();
person2.sayName(); //'james'
alert(person1.sayName == person2.sayName); //true
前面例子中每添加一個屬性和方法就要敲一遍 Person.prototype米丘。為減少
不必要的輸入剑令,也為了從視覺上更好地封裝原型的功能,更常見的做法是用一個包含所有屬性和方法的
對象字面量來重寫整個原型對象
function Person() {}
Person.prototype, = {
constructor : Person,
name : 'james',
age : 18,
sex : 'male',
sayName : function () {
alert(this,name)
}
}
以上代碼特意包含了一個 constructor 屬性拄查,并將它的值設(shè)置為 Person吁津,從而確保了通過該屬
性能夠訪問到適當(dāng)?shù)闹怠ontrucor是原型對象的一個默認(rèn)屬性堕扶,它指向構(gòu)造函數(shù)腺毫。
原型模式也不是沒有缺點(diǎn)癣疟。通過例子可以發(fā)現(xiàn)它省略了為構(gòu)造函數(shù)傳遞初始化參數(shù)這一環(huán)節(jié),結(jié)果所有實(shí)例在默認(rèn)情況下都將取得相同的屬性值潮酒。雖然這會在某種程度上帶來一些不方便,但還不是原型的最大問題邪蛔。
原型模式的最大問題是由其共享的本性所導(dǎo)致的急黎。
function Person(){
}
Person.prototype = {
constructor: Person,
name : "james",
age : 218,
sex : "male",
friends : ['Curry','Amy'],
sayName : function () {
alert(this.name);
}
};
var person1 = new Person();
var person2 = new Person();
person1.friends.push("Van");
alert(person1.friends); //'Curry,Amy,Van'
alert(person2.friends); //'Curry,Amy,Van'
alert(person1.friends === person2.friends); //true
有一個實(shí)例改變了構(gòu)造函數(shù)原型對象的數(shù)組,其他實(shí)例所引用的構(gòu)造函數(shù)的數(shù)組也會改變侧到。
4.原型+構(gòu)造函數(shù)模式
這種混合模式綜合了原型模式和構(gòu)造函數(shù)模式這兩種模式的優(yōu)點(diǎn)
function Person (name,age,sex) {
this.name = name;
this.age = age;
this.sex = sex
this.friends = ['Curry','Amy']
}
Person.prototype = {
constructor : Person,
sayName : function () {
alert(this.name)
}
}
var person1 = new Person('James',18,'male');
var person2 = new Person('Rose',20,'male');
person1.friends.push("Van");
alert(person1.friends); //"Curry,Amy,Van"
alert(person2.friends); //"Curry,Amy"
alert(person1.friends === person2.friends); //false
alert(person1.sayName === person2.sayName); //true
實(shí)例屬性都是在構(gòu)造函數(shù)中定義的勃教,而由所有實(shí)例共享的屬性 constructor 和方
法 sayName()則是在原型中定義的。而修改了 person1.friends(向其中添加一個新字符串)匠抗,并不
會影響到 person2.friends故源,因?yàn)樗鼈兎謩e引用了不同的數(shù)組。
所以我們在構(gòu)造對象的時候汞贸,一般是原型模式和構(gòu)造模式組合使用绳军,變化的用構(gòu)造模式 不變的公用的用原型模式,就像上面的這個栗子矢腻,屬性用的構(gòu)造函數(shù)门驾,因?yàn)橐话悴煌瑢ο髮傩远疾煌椒ㄓ迷湍J?/p>