一坑律、工廠模式
概念:工廠方法說白了就是在工廠里面去寫方法速缨,在外部寫一個公用的方法去調(diào)取工廠的獨有方法娘香,來實現(xiàn)客戶的需求
可以批量創(chuàng)建相同屬性和方法的對象继阻,不用每次都重新定義對象
工廠模式需要3個基本步驟,原料投入(傳參)呐伞,加工過程(new—>return)敌卓,成品出廠(return)
//工廠模式
var a = {};//不能重復(fù)的利用 設(shè)置公共屬性的代碼
// 我們需要創(chuàng)建10個cat屬性,每個對象都有 年齡姓名的屬性伶氢,包括run方法
function createCat(age, name) {//工廠模式就是標(biāo)準(zhǔn)化的生成默認對象的函數(shù)
var o = new Object();
// var o={};
o.age = age;
o.name = name;
o.run = function () {
console.log(this.name + ' running....')
}
return o;
}
var c = createCat(19, 'hhh')
var c2 = createCat(20, 'ggg')
// 優(yōu)點:
// 1趟径、可以進行批量的創(chuàng)建 都有公共的默認值和屬性對象,解決了重復(fù)創(chuàng)建對象的問題
// 缺點
// 1癣防、對象的方法不能重用蜗巧,每個對象的內(nèi)存都存儲一份函數(shù)對象的內(nèi)存
// 2、不能識別對象的原型機構(gòu)造函數(shù)
// 3蕾盯、c instance of Cat;//false
2幕屹、構(gòu)造函數(shù)創(chuàng)建對象及優(yōu)缺點
優(yōu)點
所有創(chuàng)建出來的對象,都可以找到他的原型和構(gòu)造函數(shù)
公共的屬性和方法也可以在創(chuàng)建的時候統(tǒng)一創(chuàng)建和維護
缺點
對象的函數(shù),每個對象都會擁有一份內(nèi)存拷貝望拖。浪費內(nèi)存
function Cat(name, age) {
this.age = age
this.name = name
this.run = function () {
console.log(this.name, this.age)
}
}
var c1 = new Cat('black', 3);
var c2 = new Cat('white', 2);
3渺尘、組合構(gòu)造函數(shù)模式與原型模式構(gòu)建對象
概念:組合使用構(gòu)造函數(shù)模式與原型模式
公共的屬性何方法放到原型上,獨立的屬性使用構(gòu)造函數(shù)模式说敏,放到對象自己身上
優(yōu)點:
既保證了方法等共享的屬性鸥跟,只在內(nèi)存中保存一份,節(jié)省內(nèi)存
又可以實現(xiàn)每個對象有自己單獨存放的屬性盔沫。是一種經(jīng)典的構(gòu)建對象的方法
function Cat() {
this.age = 19
// 如果需要共享的屬性和方法我們統(tǒng)一放到原型中定義
// this.run = function () {
// console.log('fun')
// }
}
Cat.prototype.name = 'black cat'
Cat.prototype.run = function () {
console.log(this.name, this.age)
}
var c1 = new Cat();
var c2 = new Cat();
console.log(c1.name)//black cat
console.log(c2.name)//black cat
// c1.run();
console.log(c1.run() === c2.run())//true
c1.name = 'white cat'
console.log(c1.name);
4医咨、穩(wěn)妥構(gòu)造函數(shù)模式
概念:
所謂穩(wěn)妥對象,指的是沒有公共屬性架诞,而且其方法也不引用this的對象
優(yōu)點
可以共享屬性和方法的初始代碼
無論用戶是否用了new還是沒有使用new都會被正確的返回新的對象
缺點
無法追溯對象的原型和構(gòu)造函數(shù)拟淮,默認沒有公共的屬性和方法,內(nèi)存浪費
function Cat() {
var o = {};
o.age = 10;
o.name = 'black cat';
o.run = function () {
console.log(o.name + ' running....')
}
// 如果返回是引用類型就將他返回侈贷,如果是基本類型就返回this
// o = { name: 'liu' };
// o = 2;//2
return o;
}
// new一個對象和不用new 是一樣的
var c1 = new Cat()//構(gòu)造函數(shù)調(diào)用
var c2 = Cat()//函數(shù)調(diào)用模式
console.log(c1)
console.log(c2)
5惩歉、對象的繼承
原型鏈繼承方式
// 動物基類
function Animal(name, age) {
this.name = name;
this.age = age;
this.fruit = ['water', 'apple']
}
// 在動物的基類上添加方法run
Animal.prototype.run = function () {
console.log(this.name + ' running')
}
function Cat(name, age) {
this.name = name;
this.age = age;
}
// 原型鏈的繼承方式
// Cat.prototype.constructor === Cat
// console.log(Cat.prototype.constructor === Cat)//true
Cat.prototype = new Animal();
//上面的代碼把cat的prototype指向了Animal 現(xiàn)在要還原回來
Cat.prototype.constructor = Cat;
console.log(Cat)
console.log(Cat.prototype.constructor)//Animal
var c = new Cat('Tom', 17)//希望cat繼承animal的屬性和方法
c.run();//從animal原型上繼承的方法
c.fruit.push('banana')
console.log(c.fruit)//["water", "apple", "banana"]
// 問題
// 1、子類的構(gòu)造函數(shù)的參數(shù)俏蛮,沒法傳給父級的構(gòu)造函數(shù)
// 2撑蚌、子類的原型的constructor會被改變,需要自己變回來
// 3搏屑、如果父類里有引用類型的屬性争涌,那么所有的子類會共享這個引用類
構(gòu)造函數(shù)繼承
// 父類
function Animal(name, age) {
this.name = name;
this.age = age;
this.fruit = ['water', 'apple']
}
// 在父類的原型上 創(chuàng)建run方法
Animal.prototype.run = function () {
console.log(this.name + ' running')
}
function Cat(name, age) {
// Animal(age,name)//this===window;
Animal.call(this, name, age)//借用父類的構(gòu)造函數(shù) 給子類創(chuàng)建實例屬性
}
var c = new Cat('Tom', 12)
console.dir(Cat.prototype.constructor)
console.log(c)// Tom
console.log(c.name)// Tom
console.log(c.age)// Tom
console.log(c.fruit)// ['water', 'apple']
組合繼承
// 父類
function Animal(name, age) {
this.name = name;
this.age = age;
this.fruit = ['water', 'apple']
}
// 在父類的原型上 創(chuàng)建run方法
Animal.prototype.run = function () {
console.log(this.name + ' running')
}
function Cat(name, age) {
// Animal(age,name)//this===window;
Animal.call(this, name, age)
}
Cat.prototype = new Animal();//組合原型繼承模式
Cat.prototype.constructor = Cat;
var c = new Cat('Tom', 12)
console.dir(Cat.prototype.constructor)
console.log(c)// Tom
console.log(c.name)// Tom
console.log(c.age)// Tom
console.log(c.fruit)// ['water', 'apple']
原型方法繼承
function object(o) {
function F() { }
F.prototype = o//讓空函數(shù)的原型指向o對象
return new F();//創(chuàng)建一個f實例,f的內(nèi)部原型指向o對象
}
var o = { name: 'liu', age: 23 }
var m1 = object(o)
console.log(m1.name)
// 優(yōu)點:
// 不需要使用new構(gòu)造函數(shù)就可以直接 構(gòu)造另外其他對象
// 缺點:
// 所有構(gòu)造函數(shù)出來的實例會共享 原型對象上的引用類型的屬性
寄生繼承方式
寄生繼承模式是在原型式繼承模式上增強原型對象的增強模式辣恋。只是對象原型式繼承的擴張而已
寄生繼承類似一個工廠模式亮垫,工廠內(nèi)部把原型對象進行構(gòu)造出另一個實例,并對構(gòu)造出來的實例進行增強伟骨,最后返回這個實例
function Person(name, age, job) {
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function() {
alert(this.name);
}
return o;
}
var person1 = new Person("Nicholas", 29, "Software Engineer");
var person2 = new Person("Greg", 27, "Doctor");
寄生組合的方式