javascript高階程式設計讀書筆記———建立物件
阿新 • • 發佈:2019-02-01
2. 建立物件的幾種方式
2.1 工廠模式
function createPeople(name, age, job) {
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function(){
console.log(this.name);
}
return o;
}
var p1 = createPeople("landy", "20", "fe");
2.2 建構函式模式
function Person (name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.sayName = function(){
console.log(this.name);
};
}
var p1 = new Person("landy", "20", "fe");
注意: 與工廠模式不同的地方主要有:
1. 沒有顯示建立物件。
2. 直接將屬性和方法賦給this物件
3. 沒有return語句
建構函式的缺點:方法無法複用。例如以上例子中的sayName函式。 我們可以將方法移到外部來實現複用。
function Person(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.sayName = sayName;
}
function sayName(){
console.log(this.name);
};
var p1 = new Person("landy", "20", "fe");
但是如果很多方法的話,就需要定義很多全域性函式,而且這些函式只能被某個物件呼叫。這種情況下,已經破壞了該引用型別的封裝性。
2.3 原型模式
function Person() {
}
Person.prototype.name = "landy";
Person.prototype.age = "20";
Person.prototype.job = "fe";
Person.prototype.sayName = function(){
console.log(this.name);
};
var p1 = new Person();
var p2 = new Person();
p1.sayName(); // landy
console.log(p1.sayName == p2.sayName) // true
方法 | 說明 |
---|---|
isPrototypeOf() | 確定物件是否存在原型關係 |
hasOwnProperty() | 確定是例項擁有某一屬性還是原型擁有該屬性 |
in | 判斷是否物件擁有某一屬性。但不能準確判斷出是例項屬性還是原型的屬性 |
function Person() {
}
var p = new Person();
Person.prototype.sayHi = function() {
console.log("hi");
}
p.sayHi(); // no error
function Person() {
}
var p = new Person();
Person.prototype = {
constructor: Person;
sayHi: function() {
console.log("hi");
}
}
p.sayHi(); // error
// 第二種情況對原型進行了重寫,p的原型是之前的person.prototype.而不是重寫後的。所以會報錯。
注意:原型模式的問題: 資料共享。
2.4 組合使用建構函式模式和原型模式
集合兩者之長,建構函式定義例項屬性,原型定義方法和constructor屬性。
function Person(name, age, job){
this.name = name;
this,age = age;
this.job = job;
}
Person.prototype = {
constructor: Person,
sayName: function() {
console.log(this.name);
}
}
注意:目前使用最廣泛,認同度最高的方式。
2.5 動態原型模式
將所有資訊封裝在建構函式中,通過建構函式初始化原型
function Person(name, age, job) {
// 屬性
this.name = name;
this.age = age;
this.job = job;
if(typeof this.sayName !== "function") {
Person.prototype.sayName = function() {
console.log(this.name);
}
}
// 在動態原型模式中,不能進行原型重寫,否則會切斷現有例項與新原型之間的聯絡
}
2.6 寄生建構函式模式
// 注意比較程式碼和工廠模式以及建構函式模式的區別
function Person(name, age, job) {
var o = new Obect();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function(){
console.log(this.name);
}
return o;
}
var p1 = new Person('landy', '20', 'fe');
// 建構函式在無返回值的時候,會預設返回新物件例項。可以使用return重寫建構函式返回的值。
注意:該種情況下,p1和建構函式Person以及Person的原型屬性沒有任何關係。所以不能使用instanceof來確定物件型別。
2.7 穩妥建構函式模式
穩妥物件是指沒有公共屬性,而且方法也不引用this物件。適合在安全環境中引用(這些環境會禁止使用 this 和 new)
funtion Person(name, age, job) {
var o = new Object();
// 在這裡定義私有變數,eg name = name;
// 有點類似C++類中的 private name = ?;
o.sayName = function(){
console.log(name);
}
return o;
}
// 以上處理通過sayName,沒有其他辦法訪問內部成員。穩妥建構函式提供了較高的安全性。