JavaScript Object (物件) -學習筆記一
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
時,物件的特性enumerable
、configurable
、get()
、set()
就不能再設定,再變動時會錯誤。value
: 設定屬性的值(key)。enumerable
:設定為false
時,此物件不可迭代,如for … in
、Object.keys()
。writable
: 設定為false
時,此物件的屬性不可賦值。get()
:物件預設的取值器,如定義此方法,就不可以再設定writable
與value
的屬性描述。set()
:物件預設的設值器,如定義此方法,就不可以再設定writable
與value
的屬性描述。
在定義物件特性前,可以使用 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
時,物件的特性enumerable
、configurable
、get()
、set()
就不能再設定,變動時會錯誤(TypeError),如下 :
let obj={}Object.defineProperty(obj,'age',{
get:function(){return 10},
configurable:false //configurable : 設定為 false 時,以下設定都會錯誤
}) //TypeErrorObject.defineProperty(obj,'age',{
enumerable:true
}) //TypeErrorObject.defineProperty(obj,'age',{
configurable:true
}) //TypeErrorObject.defineProperty(obj,'age',{
set(){}
}) //TypeErrorObject.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 … in
、Object.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)
- 判斷兩個值是否相同。
- 此方法與
==
、===
不同的是,不會自動型別轉換。 - 參數
value1
、value2
: 代表傳入的值。
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 (物件) 的學習筆記一 😉。
***如果有任何想法,也歡迎留言與我分享~***