本文是筆者學習JavaScript時做的筆記,大部分內容來自《JavaScript權威指南》,記錄學習中的重點,並引入一些其他博文和與其他程式設計師討論的內容,供本人日常翻閱。如有疑問,請留言評論,對本文的內容想深入瞭解,請支援併購買正版《JavaScript權威指南》。
一. 概述
物件是JavaScript(之後簡稱js)的基本型別之一。以下為Object的一些基本知識(隨時更新)。
-
其形式是屬性(鍵/值對)的合集,屬性名是字串,可以看做是字串到值的對映合集。
-
這種基本資料結構也被稱為,雜湊(hash)、雜湊表(hashtable)、字典(dictionary)、關聯陣列(associative array)
-
物件最重要的特徵是可以從一個被稱為原型的物件那裡繼承屬性,這種原型式繼承(prototypal inheritance)js的核心特徵。
-
物件是_可變的_,js中宣告一個物件時,是通過引用而不是通過拷貝一個副本,如下所示。
var obj = { x:1 }; console.log(obj); //列印{x:1} var obj_c = obj; obj.x = 5; console.log(obj_c); //列印{x:5} obj_c.x = 2; console.log(obj); //列印{x:2} //obj和obj_c實際上對應的是同一個物件引用,因此修改任意一個,都會對物件產生影響。 複製程式碼
-
常用的物件用法(之後會分節討論)
- 建立(create)
- 設定(set)
- 查詢(query)
- 刪除(delete)
- 檢測(test)
- 列舉(enumerate)
二. 屬性的重點
-
屬性的鍵是包含空字串在內的任意字串,且同一個物件內,不能存在相同的鍵。
-
屬性可以是任意js支援的值,或者在ES5標準下可以是一個getter和setter的函式(之後會有這兩個函式的討論)。
-
除了名字和值之外,每個屬性還有一些羽織相關的描述值,稱為屬性特性(property attribute),分別是:
- 可寫(writable attribute),表明是否可以設定該屬性的值
- 可列舉(enumerable attribute),表明是否可以通過for迴圈遍歷到該屬性
- 可配置(configurable attribute),表明是否可以刪除或者修改該屬性。
-
在es5之前,通過程式碼給物件建立的屬性都是可寫、可列舉和可配置的,在es5種可以對這些特性進行配置(之後會討論)。
-
除了包含普通屬性之外,每個物件還包含三特相關特性(object attribute)
- 物件的原型(prototype),指向一個物件,本物件可以繼承該物件的屬性。
- 物件的類(class),標識物件型別的字串。
- 物件的擴充套件標記(extensible flag)指明是否可以向該物件新增新的屬性。
三. 建立物件
(一)物件直接量
物件直接量,是指在js程式碼中,用大括號將鍵值對包含在一起,屬性之間用逗號隔開,鍵值對用冒號連線的形式直接建立一個物件。
物件直接量是一個表示式,這個表示式運算過程中,會建立並初始化一個新的物件。
var empty = {}; //沒有任何屬性的物件
var point = { x:0,y:0} //兩個屬性
var point2 = {x:point.x, y:ponit.y+1} //更多屬性
var book = {
"main title":"JavaScript", //字串中可以帶空格
"sub-title":"The Defintitive Guide", //屬性名字裡有-
"for":"all audiences", //"for"是保留字,必須用引號
author:{ //單純屬性名可以不用引號
firstname:"David"
}
}
複製程式碼
注意:
- 在ES5中,保留字可以用作不帶引號的屬性名。但是對於大部分的ES3實現,保留字作為屬性名必須用引號引起來。
- 在ES5&ES3的大部分實現中,物件直接量最後一個逗號會被忽略,但是ie中會報錯。
(二)通過new建立物件
new雲算符建立並初始化一個新物件,關鍵字new後跟隨一個函式呼叫。這裡的函式即是建構函式(constructor)。js語言核心包含內建建構函式
var o = new Object();//建立一個空物件,和{}作用相同
var a = new Array();//建立一個空陣列,和[]作用相同
var d = new Date();//建立一個表示當前時間的Date物件
var r = new RegExp("js");//建立一個進行模式匹配的RegExp物件
複製程式碼
(三) 通過Object.create()建立
1.原型 在介紹Object.create()之前,先要了解一下原型的概念。 每個js中的物件(除了null)都與一個物件相關聯,這個關聯的物件就是原型,每個物件都從原型中繼承屬性。
- 所有通過物件直接量建立的物件都具有同一個原型物件,並通過js程式碼Object.prototype獲得該物件的引用。
- 通過關鍵字new和建構函式呼叫建立的物件的原型就是建構函式的prototype屬性的值。
- js實現中,大部分物件都有原型,Object.prototype就是其中之一。
- 一個物件往上查詢,會有一個連續繼承的原型結構,這個就是是所謂的原型鏈。
2.Object.create()
ES5中定義了Object.create()的方法,它創接受兩個引數,第一個引數是這個物件的原型,第二個可選引數用以描述本物件。本函式是一個靜態函式。
var o1 = Object.create({x:1,y:2});
//o1將繼承x和y這兩個屬性。
複製程式碼
Object.create()通過傳入null,可以建立一個沒有原型的,真正意義上的空物件,該物件不會繼承任何東西,甚至不包括基本方法,如toString(),如果想建立一個普通的空物件,則必須傳入Object.prototype
var o3 = Object.create(Object.prototype);
//如此建立的o3行為和{}和new Object()完全一樣。
複製程式碼
Object可以通過原型建立物件,也就是說,你可以通過這個方法,建立一個繼承任意物件的物件,不過這個方法來自es5標準,在某些es3實現中,可以用如下方法模擬:
function inherit(p){ //inherit即為繼承,引數為要繼承的原型
if(p==null) throw TypeError(); //p不能是null
if(Object.create) //如果支援Object.create的話直接呼叫
return Object.create(p);
var t = typeof p;
if(t!=="object"&&t!=="function") throw TypeError(); //否則進一步檢測
function f(){}; //定義一個空的建構函式f
f.prototype = p; //將f的建構函式設定為p
return new f(); //使用f()建立p的繼承物件
}
複製程式碼
當然這個方法並不完善,第一inherit()不能接受null,第二inherit()不能接受第二個引數。
概述和建立物件的重點記錄到這裡,下一節將更關注物件本身的操作,我會不定期補充知識點和注意事項。