7中創建對象的方式(工廠模式、構造函數模式、原型模式、動態原型模式等分析)
阿新 • • 發佈:2018-07-29
.proto 賦值 obb this指向 好的 eat 臨時對象 struct 類型
1、工廠模式
// 定義工廠函數 function createPerson(name, age, hobby) { // 創建一個臨時object對象 var obj = new Object(); // 將工廠函數的參數賦值給臨時對象 obj.name = name; obj.age = age; obj.hobby = hobby; obj.sayName = function() { console.log("我的名字叫:"+this.name); } // 返回這個包裝好的臨時對象 return obj; } //使用工廠函數創建對象 var p1 = createPerson(‘Tom‘, 12, "sing"); var p2 = createPerson(‘mayra‘, 18, "draw");
解決問題:用於創建的批量相似對象
2、構造函數模式
// 定義構造函數 function Person(name, age, hobby) { this.name = name; this.age = age; this.hobby = hobby; this.sayName = function() { console.log("我的名字叫:"+this.name); } } // 使用構造函數實例化 var p1 = new Person(‘Tom‘, 12, "sing"); var p2 = new Person(‘mayra‘, 18, "draw");
步驟分析:
- 使用new關鍵字在內存中創建一個新對象;
- 將構造函數的this指向這個新對象;
- 使用this為這個對象添加屬性和方法
- 返回這個對象
解決的問題:構造函數可以將實例化的對象標識為一種特定的類型
存在的問題:相同的方法每次實例化都要重新創建一遍,浪費內存
3、原型模式
// 定義構造函數 function Person() { } // 定義原型 Person.prototype = { constructor: Person, //重寫constructor name: ‘Tom‘, books: [‘數學‘,‘英語‘], // 引用類型 country: "china", // 共享屬性 sayName: function () { // 共享方法 console.log("我的名字叫:" + this.name); }, }; // 使用構造函數實例化 var p1 = new Person(); var p2 = new Person(); p1.books.push(‘語文‘); console.log(p1.books); // ‘數學‘,‘英語‘,‘語文‘ console.log(p2.books); // ‘數學‘,‘英語‘,‘語文‘ p1實例影響到p2!!!
問題:屬性和方法都定義在了原型上,1、不能傳參構造不同屬性的對象 2、對於包含引用類型值的屬性來說,實例之間會相互影響
這種單獨使用原型模式的方法基本沒人使用!
4、構造函數模式和原型模式組合使用(默認使用的模式!!!)
// 定義構造函數
function Person(name, age, hobby) {
this.name = name;
this.age = age;
this.hobby = hobby;
this.books = [‘數學‘,‘英語‘]; //引用類型
}
// 定義原型(定義共享的屬性)
Person.prototype = {
constructor: Person, //重寫constructor
country: "china", // 共享屬性
sayName: function () { // 共享方法
console.log("我的名字叫:" + this.name);
},
};
// 使用構造函數實例化
var p1 = new Person(‘Tom‘, 12, "sing");
var p2 = new Person(‘mayra‘, 18, "draw");
p1.books.push(‘語文‘);
console.log(p1.books); // ‘數學‘,‘英語‘,‘語文‘
console.log(p2.books); // ‘數學‘,‘英語‘ p1實例不會影響到p2!!!
console.log(p1.country); // china
console.log(p2.country); // china
p1.sayName(); // 我的名字叫:Tom
p2.sayName(); // 我的名字叫:mayra
解決了構造函數模式共享方法多次創建問題,也解決了原型模式出現引用類型屬性時存在的問題,目前最為常用的方式
5、動態原型模式
特點:將所有信息都封裝在構造函數類,動態初始化原型
// 定義構造函數
function Person(name, age, hobby) {
this.name = name;
this.age = age;
this.hobby = hobby;
// 判斷當前是否具有sayName方法,沒有就初始化原型添加該方法
if(typeof this.sayName != ‘function‘) {
// 這個只會在第一次使用構造函數時執行
Person.prototype.sayName = function () {
console.log("我的名字叫:" + this.name);
}
}
}
// 使用構造函數實例化
var p1 = new Person(‘Tom‘,13,‘sing‘);
var p2 = new Person(‘bob‘,16,‘draw‘);
p1.sayName();
p2.sayName();
解決問題:這樣構造函數更像一個整體
6、寄生構造函數模式
function Person(name, age, hobby) {
// 創建一個臨時object對象
var obj = new Object();
// 將參數賦值給臨時對象
obj.name = name;
obj.age = age;
obj.hobby = hobby;
obj.sayName = function() {
console.log("我的名字叫:"+this.name);
};
// 返回這個包裝好的臨時對象
return obj;
}
//使用函數創建對象
var p1 = new Person(‘Tom‘, 12, "sing");
var p2 = new Person(‘mayra‘, 18, "draw");
其實就是構造函數樣子的工廠模式,意義不大,不推薦使用
7、穩妥構造函數模式
function Person(name) {
// 創建一個臨時object對象
var obj = new Object();
obj.sayName = function() {
console.log(this.name);
};
// 返回這個包裝好的臨時對象
return obj;
}
//函數創建對象
var p1 = new Person(‘Tom‘);
var p2 = new Person(‘mayra‘);
p1.sayName(); //Tom 只能通過這一種方式訪問name的值
用處:提供固定訪問成員的方法,適合在某些安全執行環境
以上不同環境下適合使用不同的模式創建對象,4、5兩種模式較為常用。
7中創建對象的方式(工廠模式、構造函數模式、原型模式、動態原型模式等分析)