对象
对象是一种数据结构(容器),采用键值对(哈希表)管理属性和方法。
:::info
属性和树节点有点类似,树节点不仅仅包含值,还有结构信息(例如:树节点中的指针来关联节点)。属性的定义不仅仅包含值,还有可读写、可配置、可迭代的特性,用于管理数据的操作。
const obj = { a: 1 }
从JS引擎的角度看,看到属性名a,其实内部隐藏的信息:
{
value: 1,
writable: false,
enumerable: true,
configurable: true
}
:::
当你在编写可执行代码时,通过对象名和属性名对数据进行访问和操作,而不需要关心实现的细节。 console.log( ‘name’ )对象中的方法执行,特别像英语的语法结构:主(console) + 谓(log) + 宾(name),句子可以描述一件事情。
属性描述(定义)
属性指一组特性的集合,不仅仅包含数据。 :::info
- 数据放到属性里,由属性的特性来决定数据如何读写。
- 数据放到变量里,由作用域、let、const决定数据如何读写。
:::
数据属性
| 特性 | type | 语义 | 默认值 | | —- | —- | —- | —- | | [[ Value ]] | any | 属性值 | undefined | | [[ Writable ]] | Boolean | 属性值是否可以重写 | false | | [[ Enumeratable ]] | Boolean | 属性是否可以迭代。for…in、…扩展运算、Object.assign、Object.key | false | | [[Configurable]] | Boolean | 如果是false,属性本身不能删除,属性描述符的所有属性值不能更改 | false |
访问器属性
特性 | type | 语义 | 默认值 |
---|---|---|---|
[[ Get ]] | function | 该函数必须是无参数 | undefined |
[[ Set ]] | function | 该函数必须是只有一个参数 | undefined |
[[ Enumeratable ]] | Boolean | 属性是否可以被迭代访问 | false |
[[Configurable]] | Boolean | 如果是false,属性本身不能删除,属性描述符的所有属性值不能更改 | false |
:::info
- 访问器属性的概念对属性值的读取之上加了一层get、set函数,感觉上同数据属性是属种关系。访问器属性抽象的层次更高,在数据属性基础上包含更多的特性。
- 访问器常用于对象属性的代理,劫持数据属性,动态计算值、校验、过滤、限制对象属性的访问。
:::
get foo( ){ },set foo(v){ },定义的就是一个访问器属性foo,不要理解成两个访问器属性。如果只定义一个set访问器,那么这个访问器属性默认的get是undefined,表明属性正常读取值。
注释说明
getter
函数必须没有参数。
//lazy-getter:一种缓存技术,当读取某个属性时,函数调用开销非常大,并且这个属性值不会变。该技术会缓存属性值,下次读取时,直接返回值,而不是再次执行函数调用。
get notifier() {
delete this.notifier; //删除访问器属性notifier
return this.notifier = document.getElementById('bookmarked-notification-anchor'); //删除了访问器属性,将计算结果放到正常的属性里。
}
setter
函数必须有一个参数,接受写入的值。
//程序在多处地方,读写某个对象中的属性,现在要更改该属性的格式,也就是要检查数据的格式。(提高程序的可扩展性)
var oldObj = {
date: '2021.8.25'
};
var newObj = {
_date: '',
get date(){
return this._date;
},
set date(val){
this._date = val.split('.').join('-');
}
};
newObj.date = '2021.8.25';
console.log(newObj.date); //2021-8-25