数据属性&访问器属性的一些细节记录

(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等操作
    ... ...
    总之,不改变原来的指向,那对象还是原来那个对象。
总结 写一篇博客比看书要花的时间多得多,但通过自己的思考,并将学习轨迹记录下来,以便以后有迹可循。

    推荐阅读