實現:利用object建構函式或者物件字面量,
缺點:使用同乙個介面建立很多物件,會產生大量重複的**
利用object例項:建立object例項然後為它新增屬性方法
var person = new object();
person.name = 'jj';
person.age = 29;
person.sayname = function()
利用物件字面量建立
var person1 =
}var person2 =
抽象了建立物件的具體過程
實現:通過傳入建構函式的引數不同得到不同的物件,解決了建立多個相似物件的問題,如下例:person1, person2都具有name, age,sayname()屬性,所以可以將這些特性封裝起來,抽象成乙個函式,工廠化生產具有相同特性的物件。
重點:抽象函式內部要先建立乙個物件,為其賦上屬性方法,一如上述沒有模式中建構函式建立物件的步驟,只是用工廠只需要這樣處理一次即可。
由於抽象的工廠函式已經返回了待建立物件,所以建立物件時只需要直接呼叫函式,傳入 引數即可,不需要使用new
缺點:沒有解決物件識別的問題,即如何知道乙個 物件的型別
function createperson(name, age)
return o;
}// 沒有new,因為工廠函式已經內部返回了待建立的物件
var person1 = createperson('jj', 29);
var person2 = createperson('qq', 39);
實現:利用new 建構函式的特點:
建立乙個物件 => 對應工廠模式中 var o = new object();
將this指向這個物件 => 工廠模式中直接使用建立的物件本身
為這個新物件新增屬性方法 => 工廠模式中直接使用物件點的形式為新物件新增屬性方法
返回新物件 => 工廠模式中也會返回新物件
優點:可以確定物件的型別,即物件的建構函式是哪個,由哪個函式構造得來的。也就意味著可以例項標識成一種特定的型別,這也是建構函式模式勝過工廠模式的地方。
方法1:建立好的物件都有乙個建構函式屬性constructor指向建構函式:person1.constructor === person; // true
原理:constructor屬性其實是借助原型物件的constructor屬性,即person1._proto_.constructor === person
方法2(更優):instanceof:person1 instanceof person; // true
原理:利用原型鏈查詢,沿著原型鏈person1._proto_._proto_.......... 是否能與person.prototype相等,然後找到向上找一層原型就找到:person1._proto_ === person.prototype
缺點:使用建構函式新增物件的方法時,會造成重複建立物件方法。即person1.sayname === person2.sayname; // false;
兩個例項中的同名方法是不同的,然而兩個方法實現的功能是相同的,這樣每次建立乙個物件就會建立乙個有過相同功能的方法,造成**冗餘,浪費記憶體。我們的目標是抽象化,對於實現相同功能的方法只需要建立一次即可,而不是每都要建立一遍,這一點又像沒有模式一樣了。
function person(name, age)
// new呼叫建構函式會自動返回新物件,相當於預設有 return o
}// 使用new來呼叫函式才是使用建構函式,才會有以上建構函式特有的特性
var person1 = new person('jj', 29);
var person2 = new person('qq', 39);
實現:將例項需要的屬性方法都定義在原型上,供所有例項共享
優點:解決了建構函式模式的缺點,即相同功能的屬性方法不用重複建立,定義在原型上即可共享使用
重點1:例項與建構函式之間沒有直接關係,是例項與建構函式的原型物件之間有關係。即:person1._proto_ === person.prototype,
_proto_是物件的原型鏈查詢方向,可以一直延伸,person1._proto_._proto_............
重點2:讀取某個物件的某個屬性時,會先從物件例項本身開始,沒有再去尋找原型物件;
為物件例項新增(賦值)乙個屬性時,會遮蔽掉原型物件中的同名屬性;即我們無法修改原型物件上屬性,但是可以遮蔽掉它。
重點3:重寫原型物件與原有的原型物件就不是乙個物件了,需要在重寫的原型物件中手動新增contructor修復指向
缺點:
省略了為建構函式傳引數這一環節,結果所有的例項預設情況下都有相同的屬性值。
針對上述缺點1,可以在例項上新增同名屬性既可遮蔽掉原型中的對應屬性。但是對於原型上的引用型別的屬性,直接通過例項修改不會建立例項自己的屬性,而是直接修改了原型物件上的共享屬性,導致其他例項的屬性也修改。
function person() {}
person.prototype =
var person1 = new person();
var person2 = new person();
person1.friends.push('cc')
console.log(person1.friends); //["aa", "bb", "cc"]
console.log(person2.friends); // ["aa", "bb", "cc"]
但是 直接重新賦值操作不會 ,只會遮蔽:
function person() {}
person.prototype =
var person1 = new person();
var person2 = new person();
person1.friends = ['cc'];
console.log(person1.friends); // ["cc]
console.log(person2.friends); // ["aa", "bb"]
原型模式建立物件:
function person() {}
person.prototype.name = 'jj';
person.prototype.age = 29;
person.prototype.sayname = function()
var person1 = new person();
var person2 = new person();
person1.name = 'qq';
person1.sayname(); // qq 來自例項
person2.sayname(); ///jj 來自原型
person1.sayname === person2.sayname; // true
實現:建構函式模式定義例項屬性,原型模式定義方法和共享的的屬性
優點:每個例項都會有自己的乙份例項屬性的副本,而且又可以共享原型上的方法,最大限度的節省了記憶體;且可以通過建構函式傳參
實現:將建構函式模式和原型模式都封裝在乙個建構函式中
function person(name, age)
}}
實現:包裝函式與工廠模式相同,只是例項化物件時通過new呼叫包裝函式,而不是直接呼叫函式
缺點:雖然是用new呼叫函式生成例項,但是並不是建構函式模式,所以建立的例項與包裝函式之間沒有任何關係,所以也不能通過instanceof判斷。畢竟包裝函式自己內部返回了物件,而不是建構函式自身預設返回的物件。
不建議使用
function person(name, age)
return o;
}// 通過new呼叫工廠模式一樣的包裝函式
var person1 = new person('jj', 29)
穩妥建構函式模式
實現:包裝函式與工廠函式相同,但是方法不引用this;例項化物件不用new,而是直接呼叫函式,畢竟包裝函式本身也返回了物件。
重點:與寄生建構函式模式相同,建立出來的物件與建構函式直接也沒有什麼關係,畢竟包裝函式本身返回了物件,所以instanceof也不起作用。
function person(name, age)
return o;
}// 不通過new例項化物件
var person1 = person('jj', 29);
person1.sayname(); // jj
超詳細的Flex布局講解
應用在 flex items上的 css 屬性 flex布局是目前web開發中使用最多的布局方案 兩個重要的概念 開啟flex布局的方法 flex布局的相容性 注意 預設情況下felx items 僅在一行中顯示,若是設定flex wrap設定為多行,那麼,當flex items 到達main en...
javascript物件導向 建立物件的幾種方式
1.字面值 var person var persons new object persons.firstname john persons.lastname doe persons.age 50 3.create來建立,通常該方法用來建立繼承物件 var child object.create p...
超詳細簡介Vue vue cli的建立
vue cli vue cli是官方提供的乙個模板 主要功能 需要的環境 node.js 在cmd輸入 node v npm v 推薦用 映象 確認已經安裝了 npm install cnpm g安裝vue cli cnpm install vue cli g建立乙個空資料夾 建立乙個基於webpa...