JavaScript Object (物件) -學習筆記一

Thomas Hung
Thomas 學習筆記
12 min readMay 4, 2020

JavaScript 中的物件是複合資料型態的集合,可以儲存多數個屬性(key-value pairs),一個屬性就是鍵(key)值(value) 之間的關聯,屬性的值(value) 可以是任何資料,如基本型別、物件、函數等…,也可以是自己定義的屬性與內容。

物件宣告

  • 物件實字

這是最常見的宣告方式,使用{} 就可以宣告 :

let obj = {
name: 'Thomas',
favorite: 'coding',
consoleName: function () {
console.log(this.name)
}
}

就如上述範例,使用{} 就可以建立一個物件,並且同時指定屬性至物件裡,這也是JSON 核心格式。

  • 物件建構式

另一個是使用 new 關鍵字來建立物件,再替物件建立屬性與方法 :

let obj = new Object()obj.name = 'Thoams'
obj.favorite= 'coding'
obj.consoleName = function () {
console.log(this.name)
}

物件的屬性 (Object Properties)

  • 屬性存取

物件的屬性可以透過 . 來存取 :

let obj = {
name: 'Thomas',
favorite: 'coding',
consoleName: function () {
console.log(this.name)
}
}
obj.favorite // 'coding'
obj.consoleName() //'Thomas'

或可以用 [ ] 來存取物件的屬性 :

let obj = {
name: 'Thomas',
favorite: 'coding',
consoleName: function () {
console.log(this.name)
}
}
obj['favorite'] // 'coding'
obj['consoleName']() //'Thomas'

[ ] 來存取物件的屬性,好處是如果屬性的索引鍵(key) 是不合法(如有空白鍵或數字),也可以存取,如下 :

let obj = {
'001': 'Thomas'
}
obj.001 // Uncaught SyntaxError: Unexpected numberobj['001'] //'Thomas'
  • 屬性新增

如果要對物件新增屬性,可以用 = 來指定 :

let obj = { }
obj.name = 'Thomas'
obj.name //'Thomas'
  • 屬性刪除

若想要刪除屬性,可以用 delete 關鍵字來刪除 :

let obj = { }
obj.name = 'Thomas'
obj.name //'Thomas'
delete obj.name
obj.name //undefined 屬性刪除後會變成 undefined
  • 判斷屬性是否存在

如果試著去存取物件的屬性,回傳是 undefined 時,那可以判斷此屬性不存在,但如果物件的屬性的值是 undefined 呢!

可以使用 in 運算子與 hasOwnProperty() 物件方法,來檢驗物件的屬性是否存在 :

let obj = {
name: 'Thomas'
}
通過 in 檢查屬性
'name' in obj //true
通過 hasOwnProperty() 檢查屬性
obj.hasOwnProperty('name') //true
obj.hasOwnProperty('favorite') //false

這兩個方式都可以檢查物件的屬性是否存在,二者的差異是 in 不只會檢查當前物件的屬性,還會向上檢查物件的原型鏈 (prototype chain), 如下 :

obj.hasOwnProperty('toString')  //false'toString' in obj  //true

這部份之後再寫關於原型鏈 (prototype chain) 的介紹。

物件的方法 (Object Methods)

Object.getOwnPropertyDescriptor(obj, prop)

  • 用來檢查物件屬性描述器的狀態。
  • 參數 obj : 表示檢查的物件。
  • 參數 prop : 表示物件的屬性。
"use strict"let obj = {
name: "Thomas"
}
Object.getOwnPropertyDescriptor(obj, "name")

Object.getOwnPropertyDescriptors(obj)

  • 用來檢查物件屬性描述器的狀態,可取得多數個屬性描述器的狀態。
  • 參數 obj : 表示檢查的物件。
"use strict"let obj = {
name: "Thomas"
}
let o = Object.getOwnPropertyDescriptors(obj)o.name.value //Thomaso.name.writable //true

Object.create(proto)

  • 用來建立物件的方法,能先設定屬性並回傳。
  • 參數 proto :代表原型的物件。
let obj = {
name: '預設值',
age: '預設值',
func: function () {
return this.name
}
}
let newObj = Object.create(obj)
console.log(newObj) //{}

會回傳空的物件 {} ,裡面有預設的屬性,也是說用 Object.create() 建立物件,並且繼承傳入參數的屬性與方法,另一種說法是參數內容變成物件的原型。

Object.defineProperty(obj, prop, descriptor)

  • 用來定義物件的屬性與特性。
  • 參數 obj : 定義屬性的物件。
  • 參數 prop : 定義屬性的名稱。
  • 參數 descriptor : 定義或修改特性的內容,特性如下。
  • configurable : 設定為 false 時,物件的特性 enumerableconfigurableget()set()就不能再設定,再變動時會錯誤。
  • value : 設定屬性的值(key)。
  • enumerable :設定為 false 時,此物件不可迭代,如 for … inObject.keys()
  • writable : 設定為 false 時,此物件的屬性不可賦值。
  • get() :物件預設的取值器,如定義此方法,就不可以再設定 writablevalue 的屬性描述。
  • set() :物件預設的設值器,如定義此方法,就不可以再設定 writablevalue 的屬性描述。

在定義物件特性前,可以使用 Object.getOwnPropertyDescriptor() ,來檢查物件屬性描述器的狀態,如下 :

let obj={}Object.defineProperty( obj,'name',{value:'thoams'} )obj1=Object.getOwnPropertyDescriptor( obj,'name' ) //輸出結果如下圖:

Object.defineProperty()取得物件的預設情況下是 false

而透過物件實字{}與物件建構式new關鍵字來建立的屬性時的預設情況是 true ,如下 :

let obj = { name:'Thomas' }obj1 = Object.getOwnPropertyDescriptor(obj,'name')  //輸出結果如下圖:
let obj = new Object()obj['name'] = 'Castle'obj1 = Object.getOwnPropertyDescriptor(obj,'name')  //輸出結果如下圖:
  • configurable 設定為 false 時,物件的特性 enumerableconfigurableget()set()就不能再設定,變動時會錯誤(TypeError),如下 :
let obj={}Object.defineProperty(obj,'age',{
get:function(){return 10},
configurable:false //configurable : 設定為 false 時,以下設定都會錯誤
}) //TypeError
Object.defineProperty(obj,'age',{
enumerable:true
}) //TypeError
Object.defineProperty(obj,'age',{
configurable:true
}) //TypeError
Object.defineProperty(obj,'age',{
set(){}
}) //TypeError
Object.defineProperty(obj,'age',{
get(){}
}) //TypeError
  • writable 設定為 false 時,此物件的屬性不可賦值,如下 :
let obj = {}Object.defineProperty(obj,'age',{
value:30,
writable:false
})
obj.age //30obj.age = 15 //此物件的屬性不可賦值obj.age //30 原值
  • enumerable 設定為 false 時,此物件不可迭代,如 for … inObject.keys(),如下 :
let obj = {}Object.defineProperty(obj,'a',{
value:10,
enumerable:false //此物件不可迭代
})
Object.defineProperty(obj,'b',{
value:20,
enumerable:true
})
Object.defineProperty(obj,'c',{
value:30 //此物件不可迭代 預設值是 false
})
obj.d = 40for(let value in obj){
obj[value] //20 40
}
Object.keys(obj) //[ 'b', 'd' ]
  • get()set()

使用 Object.defineProperty() 的方式定義屬性,如下 :

let obj = {}Object.defineProperty(obj, "name", {
configurable: true,
enumerable: true,
get() {
return this._name_
},
set(val) {
this._name_ = `Hello I am ${val}`
}
})
obj.name = "Castle"obj.name //Hello I am Castle

與使用物件實字的方式定義屬性,如下:

let obj = {
get name() {
return this._name_
},
set name(val) {
this._name_ = `Hi I am ${val}`
}
}
obj.name = "Thomas"obj.name //Hello I am Thomas

Object.defineProperties(obj, props)

  • 用來定義數個物件的屬性與特性,與 Object.defineProperty()一樣,差異在這個可以同時定義數個物件。
  • 參數 obj : 定義屬性的物件。
  • 參數 prop : 定義屬性的名稱。
let obj = {}Object.defineProperties(obj, {
'prop1': {
value: 'Thomas',
writable: true
},
'prop2': {
value: 'Castle',
writable: true
}
})
Object.getOwnPropertyDescriptor(obj, 'prop1')
Object.getOwnPropertyDescriptor(obj, 'prop2')

Object.is(value1, value2)

  • 判斷兩個值是否相同。
  • 此方法與 ===== 不同的是,不會自動型別轉換。
  • 參數 value1value2 : 代表傳入的值。
Object.is(1, 1) //true 數字是相同的Object.is(false, false) //true Object.is(true, true) //trueObject.is(null, null) //trueObject.is(undefined, undefined) //trueObject.is('abc','abc') //true 字串是同長度與順序Object.is(-0,-0) //true 同樣負值Object.is('abc','cba') //falseObject.is([], []) //falseObject.is({}, {}) //falseObject.is(-0, 0) //false

參考:Object

以上是我對 Object (物件) 的學習筆記一 😉。

***如果有任何想法,也歡迎留言與我分享~***

--

--

Thomas Hung
Thomas 學習筆記

when you feel like quitting,think about why you started.