1.單例模式
對(duì)像數(shù)據(jù)類型的作用
把描述同一個(gè)事物(同一個(gè)對(duì)像)的屬性和方法放在同一個(gè)內(nèi)存空間下风罩,起到了分組的作用糠排,這樣不同的事物之間的屬性即使屬性名相同,相互也不會(huì)起沖突超升,我們把這種分組編寫代碼的模式叫做‘單例模式’入宦。
例:
var personal1 = {
name: 'ant',
age: '20'
};
var personal2 = {
name: '張飛',
age: '32'
}
// 在上面單例模式中我們常把personal1和personal2叫做命名空間。單例模式主要解決了分組的作用室琢,但是不能批量生產(chǎn)
2.工廠模式
把實(shí)現(xiàn)同一件事情的相同代碼方到同一個(gè)函數(shù)中乾闰。工廠模式也稱‘函數(shù)的封裝’
'低耦合高內(nèi)聚': 減少頁(yè)面的冗余代碼,提高代碼的重復(fù)利用率.
例:
function createPersonal (name, age) {
var obj = {};
obj.name = name;
obj.age = age;
obj.personal = function () {
console.log('name'+ this.name + ';' + 'age' + this.age)
}
return obj
}
var p1 = createPersonal('ant', 35);
p1.personal()
3.構(gòu)造函數(shù)模式
構(gòu)造函數(shù)模式的目的是為了創(chuàng)建一個(gè)自定義類盈滴,并且創(chuàng)建這個(gè)類的實(shí)例涯肩。構(gòu)造函數(shù)模式擁有了類和實(shí)例的概念,并且實(shí)例和實(shí)例之間是相互獨(dú)立拉開的,實(shí)例識(shí)別
js中的所有類都是函數(shù)數(shù)據(jù)類型的病苗,它通過(guò)new執(zhí)行變成了一個(gè)類疗垛,但是本身也是一個(gè)普通函數(shù);js中所有的實(shí)列都是對(duì)象數(shù)據(jù)類型的铅乡。
3.1 構(gòu)造函數(shù)和工廠模式的區(qū)別:
(1)執(zhí)行的時(shí)候
1.1 普通函數(shù)的執(zhí)行 createPersonal()
1.2 構(gòu)造函數(shù)模式 new CreatePersonal() 通過(guò)new來(lái)執(zhí)行后继谚,CreatePersonal就是一個(gè)類了
// 函數(shù)的返回值p1就是CreatePersonal的一個(gè)實(shí)例
(2)在函數(shù)代碼執(zhí)行的時(shí)候
相同:都是形成了一個(gè)私有的作用域,然后形參賦值->預(yù)解釋->代碼從上到下執(zhí)行(類和普通函數(shù)一樣阵幸,有普通函數(shù)的一樣)
不同:在代碼執(zhí)行之前花履,不用手動(dòng)的創(chuàng)建對(duì)象了,瀏覽器會(huì)默認(rèn)創(chuàng)建一個(gè)對(duì)象數(shù)據(jù)類型的值(這個(gè)對(duì)象其實(shí)就是我們當(dāng)前的一個(gè)實(shí)例)挚赊。接下來(lái)代碼從上到下執(zhí)行诡壁,以前當(dāng)前實(shí)例為執(zhí)行的主體(this就是當(dāng)前的實(shí)例),然后分別把屬性名和屬性值賦值給當(dāng)前的實(shí)例荠割。瀏覽器會(huì)默認(rèn)的把創(chuàng)建的實(shí)例返回妹卿。
3.2在構(gòu)造函數(shù)模式中new Fn()執(zhí)行,如果Fn不需要傳遞參數(shù)的話蔑鹦,后面小括號(hào)可以省略夺克。
例:
function CreatePersonal (name, age) {
// 瀏覽器默認(rèn)創(chuàng)建了p1,這時(shí)候this就是指的p1
this.name = name;
this.age = age;
this.personal = function () {
console.log('name'+ this.name + ';' + 'age' + this.age)
}
// 瀏覽器把
}
var p1 = new CreatePersonal('ant', 35);
p1.personal()
var p2 = new CreatePersonal('dog', 10);
p2.personal()
// console.log(p1.personal === p2.personal) // false
// 在類中給實(shí)例增加的屬性this.xxx = xxx屬于當(dāng)前實(shí)例的私有屬性嚎朽,實(shí)例和實(shí)例之間是單獨(dú)的個(gè)體铺纽,所有私有的屬性之間是不相等的
拓展:
// js當(dāng)中所有的類都是函數(shù)數(shù)據(jù)類型的,它通過(guò)new執(zhí)行變成了一個(gè)類哟忍,但是它本身也是一個(gè)普通的函數(shù)
// js當(dāng)中所有的實(shí)例都是對(duì)象數(shù)據(jù)類型的
3.3類有普通函數(shù)的一面狡门,當(dāng)函數(shù)執(zhí)行的時(shí)候,var num是當(dāng)前函數(shù)形成的私有的作用域中的私有變量锅很,它和f1這個(gè)實(shí)例沒(méi)有任何關(guān)系其馏;只有this.xxx = xxx才相當(dāng)于給f1這個(gè)實(shí)例添加的私有的屬性和方法,才和f1有關(guān)系
例:
function Fn () {
var num = 100;
this.x = 200;
this.Fn1 = function () {
console.log(this.x)
}
}
var f1 = new Fn;
console.log(f1.num) // undefined
3.4在構(gòu)造函數(shù)模式中爆安,瀏覽器會(huì)默認(rèn)的把我們的實(shí)例返回(返回一個(gè)對(duì)象數(shù)據(jù)類型的值)叛复;但是如果我們自己手動(dòng)加一個(gè)return返回:
3.4.1返回一個(gè)基本的數(shù)據(jù)類型,當(dāng)前的實(shí)例不變扔仓;例如return 200
3.4.2返回一個(gè)引用數(shù)據(jù)類型的值致扯,當(dāng)前實(shí)例會(huì)被自己返回的給替換掉例如return {name:'ant'},這時(shí)候f2是對(duì)象{name: 'ant'}
3.5檢查某一個(gè)實(shí)例是否屬于這個(gè)類当辐,用instanceof檢測(cè)
// console.log(f1 instanceof Fn) //true
3.6 in是檢測(cè)一個(gè)屬性是否屬于這個(gè)對(duì)象 attr in object
console.log(Fn1 in f1) // true
hasOwnProperty:用來(lái)檢測(cè)某一個(gè)屬性是否為這個(gè)對(duì)象的私有的屬性,這個(gè)方法只能檢測(cè)私有的屬性
console.log(f1.hasOwnProperty('Fn1'))
function Fn () {
var num = 100;
this.x = 200;
this.Fn1 = function () {
console.log(this.x)
}
return 200
}
var f1 = new Fn;
console.log(f1.num) // undefined
console.log(f1) //還是this.x =200 ;this.Fn1 = function() {}
function Fn1 () {
var num = 100;
this.x = 200;
this.Fn1 = function () {
console.log(this.x)
}
return {name: 'ant'}
}
var f2 = new Fn1;
console.log(f2) // 返回 {name: 'ant'}
4.原形鏈模式
4.1 每一個(gè)函數(shù)數(shù)據(jù)類型(普通函數(shù)鲤看、類)都有一個(gè)天生自帶的屬性:prototype(原型)缘揪,并且這個(gè)屬性是一個(gè)對(duì)象數(shù)據(jù)類型的值。
4.2 并且在prototype上瀏覽器天生給它加上一個(gè)屬性constructor(構(gòu)造函數(shù)),屬性值是當(dāng)前函數(shù)(類)本身找筝。
4.3 每一個(gè)對(duì)象數(shù)據(jù)類型(普通對(duì)象蹈垢、實(shí)例、prototype...)也天生自帶一個(gè)屬性: _ proto_袖裕,屬性值是當(dāng)前實(shí)例所屬類的原型(prototype)
function Fn () {
var num = 100;
this.x = 200;
}
Fn.prototype.fn1 = function () {
console.log(this.x)
}
var f1 = new Fn;
console.log(Fn.prototype.constructor === Fn) // true
備注:
// 1.Object是所有數(shù)據(jù)類型的基類(最頂層的類)
// 1.1 f1 instanceof Object ->true 因?yàn)閒1通過(guò)_ proto_可以往上級(jí)查找曹抬,不管多少級(jí),最后總能找到Object
// 1.2. 在Object.prototype上沒(méi)有_ proto_這個(gè)屬性
// 2.原型鏈模式
(1)通過(guò) 對(duì)象名.屬性名 的方式獲取屬性值的時(shí)候急鳄,首先在對(duì)象的私有屬性上進(jìn)行查找谤民,如果私有中存在這個(gè)屬性,則獲取的是私有屬性的值疾宏;如果私有的沒(méi)有张足,則通過(guò)_ proto_找到所屬類的原型(類的原型上定義的屬性和方法都是當(dāng)前實(shí)例公有的屬性和方法),原型上存在的話坎藐,獲取的是公有的屬性值为牍;如果原型上也沒(méi)有,則繼續(xù)通過(guò)_ proto_繼續(xù)向上查找岩馍,一直找到Object.prototype為止碉咆。這種查找的機(jī)制就是原型鏈模式
function Fn () {
var num = 100;
this.x = 200;
this.sum = function(){}
}
Fn.prototype.fn1 = function () {
console.log(this.x)
}
Fn.prototype.sum = function () {}
var f1 = new Fn;
var f2 = new Fn;
console.log(Fn.prototype.constructor === Fn) // true
f1.sum === f2._proto_.sum // false f1.sum是私有的,f2找的sum是公有的
f1.sum === Fn.prototype.sum // false f1.sum是私有的蛀恩,F(xiàn)n找的sum是公有的
f1.sum = function () {
//修改自己私有的sum
}
f1._proto_.sum = function () {
// 修改所屬類原型上的sum疫铜,修改公有的
}
Fn.prototype.sum = function () {
// 修改公有的sum
}