1、JavaScript 把的對象定義成散列表:無序屬性的集合,其屬性可以包含基本值、對象或者函數。
2、創建對象模式
(1)最簡單的方式:創建一個 Object 的實例,併爲它添加屬性和方法。
* 存在的問題:使用同一個藉口創建很多對象,會產生大量的重複代碼。
(2)工廠模式:抽象了創建具體對象的過程,用函數來封裝以特定接口創建對象的細節。
* 存在的問題:沒有解決對象識別的問題。
(3)構造函數模式:用來創建特定類型的對象,也可以創建自定義的構造函數,從而定義自定義對象類型的屬性和方法。
* 特點:不用顯式的創建對象,而是直接將屬性和方法賦給了 this 對象,不用 return
* 使用:創建構造函數模式對象的實例,需要使用 new 操作符。
* 構造函數與普通函數的區別:任何函數,只要通過 new 操作符來調用,那它就是構造函數;沒有通過 new 操作符來調用,都是普通函數。
* 存在的問題:每個方法都要在每個實例上重新創建一遍,即每個實例都包含不同的 Function 實例。
(4)原型模式:創建的每個函數都有一個 prototype(原型)屬性,這個屬性是一個指針,指向一個對象,這個對象包含可以由特定類型的所以實例共享的屬性和方法。
* 理解原型對象:默認情況下,所有原型對象都會自動獲得一個 constructor 屬性,這個屬性包含一個指向 prototype 屬性所在函數的指針。創建自定義的構造函數後,其原型對象默認只會取得 constructor 屬性。當調用構造函數創建一個實例後,該實例的內部包含一個內部指針,指向構造函數的原型對象。在實例中,Person.prototype 指向了原型對象,而 Person.prototype.constructor 又指回了 Person
* 特點:當爲原型模型對象實例添加一個屬性時,這個屬性會屏蔽原型對象中保存的同名屬性;使用 delete 操作符可以刪除實例屬性,從而重新訪問原型屬性。
* 更簡單的原型模式語法:使用一個包含所有屬性和方法的對象字面量重寫整個原型對象,並設置 constructor 的指向。
* 存在的問題:原型模式省略了構造函數傳遞初始化參數,所以的實例都會獲得相同的屬性值。
(5)組合使用構造函數模式和原型模式:使用構造模式來定義實例屬性,使用原型模式來地定義方法和共享的屬性。
從而使得每個實例都有自己的一份實例屬性的副本,同時又共享着對方法的引用,最大限度的節省了內存。這種混成模式是創建自定義類型的最常見方法,是使用最廣泛、認同度最高的一種創建自定義類型的方法。可以說,這是用來定義引用類型的一種默認模式。
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype = {
constructor: Person,
sayName: function() {
alert(this.name);
}
};
var person = new Person("bella", 25);
person.sayName();//"bella"
6)寄生構造函數模式:創建一個函數,該函數的作用僅僅是封裝創建對象的代碼,然後再返回新創建的對象,這個函數是典型的構造函數。這種模式主要用於在特殊的情況下爲對象創建構造函數。這種模式返回的對象與構造函數或者與構造函數的原型屬性之間沒有關係。
* 創建一個具有額外方法的特殊數組,例子:
function SpecialArray() {
var values = new Array();
values.push.apply(values, arguments);
values.toPipedString = function() {
return this.join("|");
}
}
var colors = new SpecicalArray("red", "blue", "green");
alert(colors.toPipedString());//"red|blue|green"
(7)穩妥構造函數模式:指沒有公共的屬性,其方法也不引用 this 對象。這種模式主要用於一些安全的環境中,或者防止數據被其他應用程序改動時使用。這種模式返回的對象與構造函數或者與構造函數的原型屬性之間沒有關係。
function Person(name, age) {
var o = new Object();
o.sayName = function() {
alert(name);
};
return o;
}
var person = new Person("wenyi", 25);
person.sayName();//"wenyi"