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

(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';
        }
    }
数据属性&访问器属性的一些细节记录_第1张图片
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';
        }
    });
数据属性&访问器属性的一些细节记录_第2张图片
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);        // 我靠
数据属性&访问器属性的一些细节记录_第3张图片
image.png

输出:"我靠"

数据属性&访问器属性的一些细节记录_第4张图片
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]);
    }
数据属性&访问器属性的一些细节记录_第5张图片
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等操作
    ... ...
    总之,不改变原来的指向,那对象还是原来那个对象。

总结

写一篇博客比看书要花的时间多得多,但通过自己的思考,并将学习轨迹记录下来,以便以后有迹可循。

你可能感兴趣的:(数据属性&访问器属性的一些细节记录)