面向?qū)ο缶幊淌怯贸橄蠓绞絼?chuàng)建基于現(xiàn)實(shí)世界模型的一種編程模式,主要包括模塊化、多太、和封裝幾種技術(shù)。
面向?qū)ο蟮膸讉€(gè)概念
類:定義對(duì)象的特征。它是對(duì)象的屬性和方法的模板定義。<strong>(JS中萬(wàn)事萬(wàn)物皆對(duì)象)</strong>
對(duì)象(或稱實(shí)例):類的一個(gè)實(shí)例。
屬性:對(duì)象的特征,比如顏色、尺寸等。
方法:對(duì)象的行為,比如行走、說(shuō)話等。
構(gòu)造函數(shù):特定類型的對(duì)象。<strong>(首字母大寫(xiě))</strong>
繼承:子類可以繼承父類的特征。
封裝:一種把數(shù)據(jù)和相關(guān)的方法綁定在一起使用的方法。
抽象:結(jié)合復(fù)雜的繼承、方法、屬性的對(duì)象能夠模擬實(shí)現(xiàn)的模型。
多態(tài):不同的類可以定義相同的方法或?qū)傩浴?/p>
在JavaScript的面向?qū)ο缶幊讨写篌w也包括這些。不過(guò)在稱呼上可能稍有不同,JavaScript中沒(méi)有原生的“類”的概念,而只有對(duì)象的概念。
一、對(duì)象(類)的創(chuàng)建
使用構(gòu)造函數(shù)來(lái)創(chuàng)建特定類型的對(duì)象,也可以創(chuàng)建自定義的構(gòu)造函數(shù)。
//創(chuàng)建類person(構(gòu)造函數(shù))
function Person() {
}
//創(chuàng)建person對(duì)象
var person1 = new Person();
//給person對(duì)象添加屬性
person1.name = 'Tom'
person1.age = '18'
person1.gender = 'male'
//給對(duì)象添加方法
person1.show = function () {
//在函數(shù)內(nèi)部可以使用this,誰(shuí)調(diào)用這個(gè)函數(shù),this就代表誰(shuí)
console.log(this.name, this.age, this.gender);
}
構(gòu)造函數(shù)始終都應(yīng)該以大寫(xiě)字母開(kāi)頭,普通函數(shù)則以小寫(xiě)字母開(kāi)頭。必須使用new操作符。
1.創(chuàng)建新對(duì)象
2.將構(gòu)造函數(shù)的作用域賦給新對(duì)象
3執(zhí)行構(gòu)造函數(shù)
4返回新對(duì)象
二、工廠模式
創(chuàng)建一個(gè)對(duì)象常常需要復(fù)雜的過(guò)程,創(chuàng)建對(duì)象可能會(huì)導(dǎo)致大量的重復(fù)代碼,工廠方法模式通過(guò)定義一個(gè)單獨(dú)的創(chuàng)建對(duì)象的方法來(lái)解決這些問(wèn)題。
//工廠設(shè)計(jì)模式
function people(name, age) {
var obj = new Object();
obj.name = name;
obj.age = age;
obj.show = function () {
console.log(this.name, this.age);
}
return obj;
}
三、原型對(duì)象
JS中分為兩大類:原生類型和對(duì)象類型,原生類型包括:number, string, boolean, null, undefined;對(duì)象類型包括:object, array, function等。
ptototype屬性:對(duì)象類型的屬性,并非所有對(duì)象類型都有prototype屬性,一般只有function對(duì)象才有prototype屬性它指向一個(gè)對(duì)象。
function Person(name, age) {
this.name = name;
this.age = age;
this.show = function () {
console.log(this.name, this.age);
}
}
var p = new Person('Atom', 20);
//給Person這個(gè)構(gòu)造函數(shù)添加“gender”屬性
Person.prototype.gender = "male"
//添加給Object(JS中Object是所有構(gòu)造函數(shù)的父級(jí)(原型對(duì)象),給Object添加屬性,同時(shí)也會(huì)給所有構(gòu)造函數(shù)的添加同樣的屬性)
Object.prototype.index = 666;
Object.prototype.show = function () {
console.log(this);
};(此時(shí)Person這個(gè)構(gòu)造函數(shù)也擁有index這個(gè)屬性和show這個(gè)方法)
console.log(p.gender);
console.log(p.index);
如下圖

四、原型鏈以及原型鏈繼承
1.每個(gè)構(gòu)造函數(shù)都有一個(gè)原型對(duì)象(prototype)
2.原型對(duì)象包含一個(gè)指向構(gòu)造函數(shù)的指針(constructor)
3.實(shí)例都包含一個(gè)指向原型對(duì)象的內(nèi)部指針([[Prototype]])
讓原型對(duì)象等于另一個(gè)類型(構(gòu)造函數(shù))的實(shí)現(xiàn),此時(shí)原型對(duì)象將包含只想另一個(gè)原型的指針,相應(yīng)的,另一個(gè)原型中也包含著一個(gè)指向另一個(gè)構(gòu)造函數(shù)的指針。如此層層遞進(jìn),就形成了原型鏈。
//構(gòu)造函數(shù)
function Person(name, age) {
this.name = name;
this.age = age;
this.show = function () {
console.log(this.name, this.age);
};
}
//讓Student繼承Person
funtion Student(name, age, major) {
//讓this調(diào)用Person構(gòu)造函數(shù),name/age作為參數(shù)傳遞
//Person.call(this, name, age);
Person.apply(this, arguments);
//處理自己特殊的屬性和方法
this.major = major;
this.show = function () {
console.log(this.name, this.age, this.major);
};
}
//新建一個(gè)對(duì)象
var stu = new Student('3Dge', '20', 'PS和3D');
stu.show();
如下圖

//創(chuàng)建構(gòu)造函數(shù)Obj1
function Obj1(a, b) {
this.a = a;
this.b = b;
this.test = function () {
console.log(this.a, this.b);
}
}
//給這個(gè)構(gòu)造函數(shù)添加attr屬性和test2方法;
Obj1.prototype = {
attr:"123";
test2:function () {
console.log('test2');
}
}
如下圖

//創(chuàng)建構(gòu)造函數(shù)Obj2
function Obj2(a, b, c) {
Obj1.apply(this, arguments);
this.c = c;
}
//讓Obj2繼承Obj1的屬性和方法
//Obj2.prototype = Obj1.prototype一定是緊跟在繼承函數(shù)(即函數(shù)Obj2)后面的不然會(huì)出BUG
Obj2.prototype = Obj1.prototype;
var obj2 = new Obj2(12, 23, 34);
console.log(obj2.attr);
obj2.test2();
如下圖
