JS Object Type
JS中的對象(Object)是比較複雜的. 在ECMA中的定義還是比較清晰的;
這裏翻譯一下, 分享給大家.
因爲本節內容有許多的表格, 我有翻譯, 但也給了大家鏈接, 原版的可以自己查閱.
原文地址: ECMAScript Object Type
The Object Type
對象(Object) 是屬性的邏輯上的集合(collection).
每個一個屬性(property) 不是 數據屬性(data property)
就是 訪問器屬性 (accessor property)
數據屬性的key值與ECMAScript語言的值和一系列布爾類型(Boolean)的特徵(attributes)相關聯. (後面有解釋)
訪問器屬性的key值與一個或兩個訪問器函數以及一系列布爾類型(Boolean)的特徵(attributes)相關聯.
訪問器函數被用於存儲和查詢相關聯的屬性的ECMAScript語言值.
屬性(Properties) 通過 key 識別.
一個屬性的key 有兩種類型
- String (包括空字符串)
- Symbol
屬性名是一個屬性鍵,它是一個字符串值。
ECMAScript語言值 就是 JS 中的數據值, 例如 null, undefined , object 等等
一個整型的索引(index)是一個 String-valued 的屬性key, 它是規範的數字字符串, 並且它的數字值範圍是 +0(正數0) 和 2^53 -1 之間.
一個數組的索引是一個整數索引, 它的範圍是在 +0 到 2^32 -1 之間.
如果, 使用數字作爲key, 會默認轉成字符串. 但是, 在數據超過 2^53 -1 時, 會使用科學計數法.
var q = {
8390812903912839012903891839018390129381938912083918390131830912839: 'hello'
}
// undefined
q['8390812903912839012903891839018390129381938912083918390131830912839']
// hello
q['8.390812903912838e+66']
屬性的key用於存取屬性和它們的值.
這又兩種不同的存取屬性. get 和 set, 對應着獲取和分配.
屬性通過get 和 set來存取
- 這個對象自己擁有的屬性
- 通過繼承關係來指向到另一個相關聯的對象的屬性
繼承的屬性(Inherited properties)
可以是它自己的屬性, 也又可能是它從另外一個相關聯的對象中繼承而來的.
對象的每個屬性都必須具有一個鍵值,該鍵值與該對象的其他屬性的鍵值不同。
所有對象都是屬性的邏輯集合. 有多種形式的對象,它們在訪問和操作屬性時的語義上各不相同
Property Attributes
特徵用於定義和解釋對象屬性的狀態(state).
Attributes of a Data Property
一個數據屬性和它關聯的的值以及特徵在下面的表格中
屬性名 | 值域 | 描述 |
---|---|---|
[[Value]] | 任意ECMA語言的值 | 通過get 來獲取到的值 |
[[Writable]] | Boolean | 如果是false, 嘗試改變 [[Value]]的操作都將失敗 |
[[Enumerable]] | Boolean | 如果是true, 這個屬性可以被for-in 枚舉. 否則, 這個屬性是 不可枚舉的 |
[[Configurable]] | Boolean | 如果設置位false, 嘗試刪除, 改變這個屬性的特徵的操作都將失敗.(無論是[[Value]]還是[[Writable]]) |
Attributes of an Accessor Property
訪問器屬性, 相關的特徵如下表
Table 4: Attributes of an Accessor Property
屬性名 | 值域 | 描述 |
---|---|---|
[[Get]] | Object 或者 Undefined | 如果是對象,必須是函數對象. 這個函數的[[Call]]內部方法是一個被空參數列表調用的, 用於查詢這個屬性值.每次獲取屬性時,執行它. |
[[Set]] | Object 或者 Undefined | 如果是對象,必須是函數對象, 這個函數的[[Call]]內部方法是一個帶有一個要賦值的值參數的函數.在每次給屬性賦值時執行.屬性的[[Set]]內部方法的效果可能(但不是必需的)影響後續調用該屬性的[[Get]]內部方法返回的值。 |
[[Enumerable]] | Boolean | 如果是true, 這個屬性可以被for-in 枚舉. 否則, 這個屬性是 不可枚舉的 |
[[Configurable]] | Boolean | 如果設置位false, 嘗試刪除, 改變這個屬性的特徵的操作都將失敗.(無論是[[Value]]還是[[Writable]]) |
Default Attribute Values
如果初始化的特徵的值沒有被顯式指定, 默認值如下表
Table 5: Default Attribute Values
Attribute Name | Default Value |
---|---|
[[Value]] | undefined |
[[Get]] | undefined |
[[Set]] | undefined |
[[Writable]] | false |
[[Enumerable]] | false |
[[Configurable]] | false |
結合MND 學習
前面說的有些模糊, 我們結合通過MDN, 一起來學習一下 屬性.
MDN 中講解的很好, 我就不重複寫例子了.
Object Internal Methods and Internal Slots
在ECMAScript中, 對象的實際語義是通過內部方法(internal methods)
的算法所指定的.
在ECMAScript引擎中的每一個對象都和一系列內部方法相關.這些內部方法定義了對象的運行時行爲(runtime behaviour)
.
這些內部方法不是ECMAScript語言的一部分. 它們被文檔所定義存粹是爲了說明的目的.
然而, ECMAScript實現中的每個對象都必須按照與其關聯的內部方法指定的行爲.
說人話, 就是JS中的對象的行爲, 其實是由一些內部方法來控制的. 但是, 這些方法不屬於JS層面, 而是屬於更底層的實現.
內部方法的名稱是多態的(polymorphic). 這就意味着當一個常見的內部方法被調用時, 不同的對象值可能執行不同的算法.
調用內部方法的實際對象是調用的“目標”。
在運行時, 如果一個算法的實現嘗試使用一個對象的不支持的內部方法, 會拋出 TypeError
的異常.
內部插槽(Internal slots)
對應着內部狀態(internal state)
, 它與對象相關聯, 並且被多種ECMAScript規範算法所引用.
內部插槽不是對象的屬性, 它們不會被繼承.
取決於具體的內部插槽規範, 許多狀態可能包含多個ECMAScript語言類型或者ECMAScript規範類型.
除非由特別的說明, 內部插槽是在創建對象的過程中分配的,不能動態地添加到對象中.
除非由特別的說明,內部插槽的初始值是undefined.
說明中創建對象的多種算法有內部插槽.然而, ECMAScript語言沒有提供直接與一個對象內部插槽交互的方式.
ECMAScript規範類型是指 Reference, List, Completion, Property Descriptor, Lexical Environment, Environment Record, Abstract Closure, and Data Block. 它們是用於描述語義
元值(meta-value)
這個之後可能給大家翻譯一下.
內部方法和內部插槽在本說明文檔中通過兩個方括號 [[]]
來特指.
表6 總結了本規範使用的基本內部方法,這些方法適用於ECMAScript代碼創建或操作的所有對象。
每個對象都必須有用於所有基本內部方法的算法。但是,並非所有對象都對這些方法使用相同的算法。
這個表是一個說明意義的表, 寫了一些常用的內部方法和內部插槽.
普通的對象(ordinary object)
是需要滿足下面的條件的
- 所有在表6 定義的方法, 和普通對象的內部方法和內部插槽
- 如果對象有 [[Call]] 的內部方法, 需要有對應的實現
- 如果對象有 [[Construct]] 的內部方法,需要有對應的實現
Ordinary Object Internal Methods and Internal Slots
所有的普通對象有一個內部插槽 [[Prototype]]
. 這個內部插槽的只可以是 null 或者 一個對象.
它可以被用於繼承.
- 數據屬性的 [[Prototype]]對象可以被繼承(也是對子對象可見的), 可以讀, 但是不能修改.
- 訪問器屬性可能繼承get和set.
每一個普通對象都有一個布爾類型值的內部插槽 [[Extensible]] . 它被用於實現可拓展相關的內部方法不變量.
換句話說, 一旦一個對象的[[Extensible]]被設置位false, 它就不再可能給這個對象加入屬性, 來修改這個對象的[[Prototype]],
除非改變這個對象[[Extensible]]爲true.
原文中有許多內部方法的定義;
有興趣可以看看.
sec-ordinary-object-internal-methods-and-internal-slots
關於對象還有, 外來對象(exotic object), 固有對象(Intrinsic Objects)等等.
精力有限, 就沒有翻譯.
感興趣可以去ECMA的官網看看.