引言 JavaScript中,可以通過對象直接量,關鍵字new(ECMAScript 5中的)Object.create(),函數來創建對象。 對象直接量 JavaScript中使用對象直接量來創建對象是最簡單的方式。對象直接量是由若幹名/值對組成的映射表,名/值對中間用冒號分隔,名/值對之間用逗號 ...
引言
JavaScript中,可以通過對象直接量,關鍵字new(ECMAScript 5中的)Object.create(),函數來創建對象。
對象直接量
JavaScript中使用對象直接量來創建對象是最簡單的方式。對象直接量是由若幹名/值對組成的映射表,名/值對中間用冒號分隔,名/值對之間用逗號分隔,整個映射表用花括弧括起來。
屬性名可以是JavaScript標識符也可以是字元串直接量,屬性值可以是任意類型的JavaScript表達式、表達式的值。
- 在ECMAScript 5(以及ECMAScript 3的一些實現)中,保留字可以用做不太帶引號的屬性名,但是對於ECMAScript 3來說,使用保留字作為屬性名必須使用引號引起來。
- 在ECMAScript 5中,對象直接量中的最後一個屬9性後的逗號將忽略,且在ECMAScript 3的大部分實現也可以忽略這個逗號,但是IE中則報錯。
對象直接量是一個表達式,每次運算都需要創建並初始化一個新對象。每次計算對象直接量的時候,都會計算該對象每個屬性的值。也就是說,如果在一個重覆調用的函數中的迴圈體內使用了對象直接量,它將創建很多新對象,並每次創建的對象的屬性也有可能有所不同。
通過new創建對象
new運算符創建並初始化一個新對象,例如:
var o = new Object(); // 創建一個空對象,和{}一樣
var a = new Array(); // 創建一個空數組,和[]一樣
var d = new Date(); // 創建一個表示當前時間的Date對象
var r = new RegExp("js"); // 創建一個可以進行模式匹配的RegExp對象
原型
每一個JavaScript對象(null除外)都和另一個對象相關聯,“另一個”對象就是我們熟知的原型,每一個對象都從原型繼承屬性。
所有通過對象直接量創建的對象都具有同一個原型對象,並可以通過JavaScript代碼Object.prototype獲取對原型對象的引用。通過關鍵字new和構造函數調用創建的對象的原型就是構造函數的protopype屬性的值。因此,同使用{}創建對象一樣,通過new Object()創建的對象也繼承自Object.prototype。同樣,通過new Array()創建的對象的原型就是Array.prototype,通過new Date()創建的對象的原型就是Date.prototype。
補充
- 沒有原型的對象不多,Object.prototype便是其中之一,它不繼承任何屬性。
- 所有的內置構造函數(以及大部分自定義的構造函數)都具有一個繼承自Object.prototype的原型。
Object.create()
ECMAScript 5定義了一個名為Object.create()方法,用於創建一個新對象,其中第一個參數是這個對象的原型,第二個參數可選,用於對對象的屬性進一步描述。
Object.create()是一個靜態函數,而不是提供給某個對象調用的方法。使用它的方法很簡單,只須傳入所需的原型對象即可:
var o1 = Object.create({x:1,y:2}); // o1繼承了屬性x和y
可以通過傳入參數null來創建一個沒有原型的新對象,但是通過這種方式創建的對象不會繼承任何東西,甚至不包括基礎方法,比如toString(),也就是說,它將不能和“+”運算符一起正常工作:
var o2 = Object.create(null); // o2不繼承任何屬性和方法
如果想創建一個普通的空對象(比如通過{}或new Object()創建的對象)。需要傳入Object.prototype:
var o3 = Object.create(Object.prototype); // o3和{}和new Object()一樣
可以通過任何原型創建新對象(換句話說,可以使任意對象可繼承),這是一個強大的特性,在ECMAScript 3中可以如下代碼來模擬原型繼承:
// inherit()返回了一個繼承自原型對象p的屬性的新對象
// 這裡使用ECMAScript 5中的Object.create()函數(如果存在的話)
// 如果不存在Object.create(),則退化使用其他方法
function inherit(p) {
if (p == null) {
throw TypeError(); // p是一個對象
}
if (Object.create) { // 如果Object.create()存在
return Object.create(p); // 直接使用它
}
var t = typeof p; // 否則進行進一步檢測
if(t !== 'object' && t !== 'function') {
throw TypeError();
}
function f() {}; // 定義一個空構造函數
f.prototype = p; // 將其原型屬性設置為p
return new f(); // 使用f()創建p的繼承對象
}