本篇文章主要介紹了JavaScript創建物件的多種方式以及優缺點,主要介紹了5種方式,有興趣的可以了解下
寫在前面
這篇文章講解創建物件的各種方式,以及優缺點。
但注意:
這篇文章比較像是筆記,因為《JavaScript高階程式設計》寫得真是太好了!
1. 工廠模式
function createPerson(name) { var o = new Object(); o.name = name; o.getName = function () { console.log(this.name); }; return o; } var person1 = createPerson('kevin');
缺點:物件無法識別,因為所有的實例都指向一個原型
2. 建構子模式
function Person(name) { this.name = name; this.getName = function () { console.log(this.name); }; } var person1 = new Person('kevin');
優點:實例可以辨識為一個特定的型別
缺點:每次建立實例時,每個方法都要被建立一次
2.1 建構函式模式最佳化
function Person(name) { this.name = name; this.getName = getName; } function getName() { console.log(this.name); } var person1 = new Person('kevin');
優點:解決了每個方法都要重新建立的問題
缺點:這叫啥封裝…
3. 原型模式
#function Person(name) { } Person.prototype.name = 'keivn'; Person.prototype.getName = function () { console.log(this.name); }; var person1 = new Person();
優點:方法不會重新建立
##缺點:1. 所有的屬性與方法都共用2. 不能初始化參數
#3.1 原型模式最佳化
function Person(name) { } Person.prototype = { name: 'kevin', getName: function () { console.log(this.name); } }; var person1 = new Person();
3.2 原型模式最佳化
function Person(name) { } Person.prototype = { constructor: Person, name: 'kevin', getName: function () { console.log(this.name); } }; var person1 = new Person();
function Person(name) { this.name = name; } Person.prototype = { constructor: Person, getName: function () { console.log(this.name); } }; var person1 = new Person();
優點:該共享的共享,該私有的私有,使用最廣泛的方式
#缺點:有的人就是希望全部都寫在一起,即更好的封裝性
4.1 動態原型模式function Person(name) {
this.name = name;
if (typeof this.getName != "function") {
Person.prototype.getName = function () {
console.log(this.name);
}
}
}
var person1 = new Person();
#解釋下為什麼:
function Person(name) { this.name = name; if (typeof this.getName != "function") { Person.prototype = { constructor: Person, getName: function () { console.log(this.name); } } } } var person1 = new Person('kevin'); var person2 = new Person('daisy'); // 报错 并没有该方法 person1.getName(); // 注释掉上面的代码,这句是可以执行的。 person2.getName();
為了解釋這個問題,假設開始執行var person1 = new Person('kevin')。
如果對 new 和 apply 的底層執行過程不是很熟悉,可以閱讀底部相關連結中的文章。
我們回顧下new 的實作步驟:
function Person(name) { this.name = name; if (typeof this.getName != "function") { Person.prototype = { constructor: Person, getName: function () { console.log(this.name); } } return new Person(name); } } var person1 = new Person('kevin'); var person2 = new Person('daisy'); person1.getName(); // kevin person2.getName(); // daisy
5.1 寄生建構子模式
function Person(name) { var o = new Object(); o.name = name; o.getName = function () { console.log(this.name); }; return o; } var person1 = new Person('kevin'); console.log(person1 instanceof Person) // false console.log(person1 instanceof Object) // true
寄生建構子模式,我個人認為應該這樣讀:
陣列
,但是又不想直接修改Array建構函數,我們可以這樣寫:##
function SpecialArray() { var values = new Array(); for (var i = 0, len = arguments.length; i len; i++) { values.push(arguments[i]); } values.toPipedString = function () { return this.join("|"); }; return values; } var colors = new SpecialArray('red', 'blue', 'green'); var colors2 = SpecialArray('red2', 'blue2', 'green2'); console.log(colors); console.log(colors.toPipedString()); // red|blue|green console.log(colors2); console.log(colors2.toPipedString()); // red2|blue2|green2
但作者可能是希望能像使用普通 Array 一樣使用 SpecialArray,雖然把 SpecialArray 當成函數也一樣能用,但這並不是作者的本意,也變得不優雅。
在可以使用其他模式的情況下,不要使用這種模式。
但值得一提的是,上面範例中的
循環:
for (var i = 0, len = arguments.length; i len; i++) { values.push(arguments[i]); }
values.push.apply(values, arguments);
5.2 穩妥建構子模式
function person(name){ var o = new Object(); o.sayName = function(){ console.log(name); }; return o; } var person1 = person('kevin'); person1.sayName(); // kevin person1.name = "daisy"; person1.sayName(); // kevin console.log(person1.name); // daisy
引用
this 的物件。
與寄生建構子模式有兩點不同:
新建立的實例方法不引用this
不使用new 運算子呼叫建構子
穩健物件最適合在一些安全的環境。
穩健建構函式模式也跟工廠模式一樣,無法辨識物件所屬型別。
以上是JavaScript創建物件的多種方式以及優缺點的深入理解的詳細內容。更多資訊請關注PHP中文網其他相關文章!