对象定义
ECMAScript把对象定义为:无序属性的集合,其属性可以包含基本值、对象或者函数。严格来说,这就是相当于说对象是一组没有特定顺序的值。对象的每个属性或方法都有一个名字,而每个名字都映射到一个值。其中值可以是数据或者函数。 每一个对象都是基于一个引用类型创建的,这个引用类型可以是原生类型,也可以是开发人员定义的类型。
属性类型
ECMAScript 中有两种属性:数据属性和访问器属性
数据属性
数据属性有4个描述行为的特性:
- [[Configurable]]:表示能否通过delete删除属性从而重新定义属性,默认值为true
- [[Enumerable]]:表示能否通过for-in循环返回属性,默认值为true
- [[Writable]]:表示能否修改属性的值,默认值为true
- [[Value]]:表示这个属性的数据值,默认为undefined
修改数据属性默认值
使用object.defineProperty()方法(注意:使用object.definedProperty方法创建一个新的属性时,如果不指定,configurable、enumerable和writable这些特性都默认为false)
- 例子
const person = {name: 'Li'}
Object.defineProperty(person, 'name', {
writable: false,
value: 'Joy'
})
// {name: "Joy"}
console.log(person)
person.name = 'test'
// 因为设置了writable: false所以name的值不能被修改
// {name: "Joy"}
console.log(person)
- 修改configurable属性 设置configurable为false,表示不能从对象中删除属性,而且,一旦configurable设置为false就不能把它再重新设置回true了,再调用object.definedProperty方法修改writeable之外的特性都会报错。
let person = {name: 'Li'}
Object.defineProperty(person, 'name', {
configurable: false,
writable: false,
value: 'Joy'
})
console.log(person)
// 抛出错误
Object.defineProperty(person, 'name', {
configurable: true,
value: 'Li'
})
console.log(person)
访问器属性
访问器属性有如下4个特征:
- [[configurable]]:表示能否通过delete删除属性从而重新定义属性,默认为true
- [[enumerable]]:表示能否通过for-in循环返回属性,默认为true
- [[get]]:在读取属性时调用的函数,默认值为undefined
- [[set]]:在写入属性值时调用的函数,默认值为undedined
使用object.defineProperty方法来定义访问器属性
以下代码创建了一个book对象,并定义了两个默认属性: _year和edition,_下划线表示_year这个属性只能通过对象方法访问的属性。(只是一种记号)
let book = {
_year: 2004,
edition: 1
}
Object.defineProperty(book, 'year', {
get: function() { return this._year },
set: function(newValue) {
if(newValue > 2004) {
this._year = newValue
this.edition += newValue - 2004
}
}
})
book.year = 2005
// {_year: 2005, edition: 2}
console.log(book)
使用Object.defineProperties定义多个属性
let book = {};
Object.defineProperties(book, {
_year: {
writable: true,
value: 2021
},
edition: {
writable: true,
value: 1
},
year: {
get: function() { return this._year },
set: function(newValue) {
if(newValue > 2004) {
this._year = newValue
this.edition += newValue - 2004
}
}
}
})
book.year = 2005
console.log(book)
注意
-
只指定getter意味着属性是不能写的,非严格模式尝试写入属性会被忽略,严格模式会抛出错误
-
只指定setter意味着不能读,非严格模式会返回undefined,严格模式会抛出错误
读取属性特征
Object.getOwnPropertyDescriptor方法,可以取得给定属性的描述符。
let book = {};
Object.defineProperties(book, {
_year: {
writable: true,
value: 2021
},
edition: {
writable: true,
value: 1
},
year: {
get: function() { return this._year },
set: function(newValue) {
if(newValue > 2004) {
this._year = newValue
this.edition += newValue - 2004
}
}
}
})
book.year = 2005
// {value: 2005, writable: true, enumerable: false, configurable: false}
console.log(Object.getOwnPropertyDescriptor(book, '_year'))