《用得上的前端知识》系列 - 你我都很忙,能用100字说清楚,绝不写万字长文
对象属性的分类
ES5 规范中,JavaScript 对象的属性可以分为数据属性和访问器属性。数据属性一般用于存储数据,而访问器属性一般用于进行 set/get 操作,但不能直接存储数据。
注:在 ECMA-262 中定义了一些用两对方括号括起来的内部属性(如:[[configurable]]、[[writable]]),用于实现JavaScript 引擎,这些属性是写给引擎看的,在编码中无法直接访问。
数据属性
数据属性有 4 个行为特性:
- [[configurable]]
-
- 表示能否通过 delete 删除属性,从而重新定义属性;
- 能否修改属性的特性;
- 能否把属性修改为访问器属性。
- 默认值为 true。
- [[enumerable]]
-
- 表示能否通过 for-in 循环遍历属性;
- 默认值为 true。
- [[writable]]
-
- 表示能否修改属性的值;
- 默认值为 true。
- [[value]]
-
- 包含这个属性的数据值;
- 读取属性值的时候,从这个位置读取;
- 写入属性值的时候,把新值保存在这个位置;
- 默认值为 undefined。
访问器属性
访问器属性最大的作用就是通过 set 方法修改属性的值,通过 get 方法获取属性的值,它有 4 个特性:
- [[configurable]]
-
- 表示能否通过 delete 删除属性,从而重新定义属性;
- 能否修改属性的特性;
- 或者能否把属性修改为数据属性;
- 对于直接在对象上定义的属性,这个特性的默认值为 true。
- [[enumerable]]
-
- 表示能否通过 for-in 循环遍历属性;
- 对于直接在对象上定义的属性,这个特性的默认值为 true。
- [[get]]
-
- 在读取属性时调用的函数;
- 默认值为 undefined。
- [[set]]
-
- 写入属性时调用的函数;
- 默认值为 undefined。
注意:一个属性不可能同时属于“数据属性”和“访问器属性”,也就是说,如果为属性指定了 [[value]] 特性的值,原则上就不能为其设置 [[get]] 特性和 [[set]] 特性的值。
访问器属性不能直接定义,必须使用Object.defineProperty()来定义。
let obj = {
name : 'xq'
}
Object.defineProperty(obj, 'name', {
set(){
console.log('有人设置为 name 属性赋值!');
},
get(){
console.log('有人读取 name 属性!');
}
});
obj.name = 'cool';
console.log( obj.name );
// output:
// 有人设置为 name 属性赋值!
// 有人读取 name 属性!
// 应用场景:数据双向绑定