数据属性&访问器属性的一些细节记录
(1)数据属性和访问器属性都有直接字面量语法,当用直接字面量语法定义时,两种属性共有的[[Configurable]]
和[[Enumerable]]
特性默认为true
,而数据属性的[[Writable]]
特性也默认为true
,访问器属性的[[Set]]
特性为undefined
。
var person = {
name: 'ceido'
}var desciptor = Object.getOwnPropertyDescriptor(person, 'name');
for (key in desciptor) {
console.log(key + ": " + desciptor[key]);
}
文章图片
image.png
var person = {
get name() {
return 'ceido';
}
}
文章图片
image.png (2)当用
Object.defineProperty
定义时,两种属性共有的[[Configurable]]
和[[Enumerable]]
特性默认为false
,而数据属性的[[Writable]]
特性也默认为false
,访问器属性的[[Set]]
特性为undefined
。var person = {}Object.defineProperty(person, 'name', {
value: 'ceido'
});
文章图片
image.png
var person = {}Object.defineProperty(person, 'name', {
get() {
return 'ceido';
}
});
文章图片
image.png (3)当数据属性和访问器属性同名时,在后面的覆盖前面的。
var person = {
name: '我靠',
get name() {
return 'ceido';
}
}console.log(person.name);
// ceido
var person = {
get name() {
return 'ceido';
},
name: '我靠'
}console.log(person.name);
// 我靠
文章图片
image.png 输出:"我靠"
文章图片
image.png
输出: "ceido"
这里3、4加上
configurable: true
,前面讲到用Object.defineProperty
定义时,[[Configurable]]
特性默认为false
,再调用Object.defineProperty
时会报错。【数据属性&访问器属性的一些细节记录】(5)
Object.defineProperty
对于已有的属性的定义,不会修改其默认特性。这是犀牛书p136上的一句话。
var person = {
name: '我靠'
}
Object.defineProperty(person, 'name', {
get() {
return 'ceido';
}
});
console.log(person.name);
var desciptor = Object.getOwnPropertyDescriptor(person, 'name');
for (key in desciptor) {
console.log(key + ": " + desciptor[key]);
}
文章图片
image.png 对于这句话,我注意的点是:对于(3)所说的覆盖,是不是该改为是对特性的修改?
首先
name
为数据属性,由(1)可知:[[Configurable]]
和[[Enumerable]]
特性默认为true
。然后使用Object.defineProperty
再定义name
,由(2)可知:[[Configurable]]
和[[Enumerable]]
特性默认为false
。按照(3)的理解,后面的定义应该会覆盖前面的,那
[[Configurable]]
和[[Enumerable]]
应该都为false。可是最后输出的为还是都为true
。所有我理解为:属性还是原来的属性,只是对特性进行了修改,而不是完全的替换。或者这样说:本来就那个属性,然后只是再对它进行一些修改而已。当然了,以上是我个人的理解,哈哈。
另外对于属性的内部特性结构,阮一峰老师的这篇有讲到。但个人觉得他后面的内容根本没有解释清楚他标题所要讲的。
(6)在getter中访问自身、在setter中设置自身,将导致无限循环。
var person = {};
Object.defineProperty(person, 'name', {
get() {
return this.name;
},
set(newVal) {
this.name = newVal;
}
});
console.log(person.name);
person.name = '我靠';
文章图片
image.png (7)访问器属性如果是对象类型,只要是不改变其指向,就不会触发setter。具体体现为:
- 删除对象属性或给对象添加属性
- 数组的push、shift等操作
... ...
总之,不改变原来的指向,那对象还是原来那个对象。
推荐阅读
- JAVA(抽象类与接口的区别&重载与重写&内存泄漏)
- 第6.2章(设置属性)
- Docker应用:容器间通信与Mariadb数据库主从复制
- 宋仲基&宋慧乔(我们不公布恋情,我们直接结婚。)
- 21天|21天|M&M《见识》04
- 使用协程爬取网页,计算网页数据大小
- Java|Java基础——数组
- Python数据分析(一)(Matplotlib使用)
- Jsr303做前端数据校验
- Spark|Spark 数据倾斜及其解决方案