JavaScript 理解对象 1 属性类型

一个用对象字面量语法写出的实例:

        var person = {
            name: "Neo",
            age: "30",
            job: "Software Engineer",
            sayName: function() {
                console.log(this.name);
            }
        };

        person.sayName();
属性类型
  1. 数据属性
  • [[Configurable]]:表示能否通过 delete 删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性。默认值为 true。
  • [[Enumerable]]:表示能否通过 for-in 循环返回属性。默认值为 true。
  • [[Writable]]:表示能否修改属性的值。默认值为 true。
  • [[Value]]:包含这个属性的数据值。读取属性值的时候,从这个位置读;写入属性值的时候,把新值保存在这个位置。默认值为 undefined。向前面的示例那样,创建了一个 name 属性,也就是 [[Value]] 特性将被设置为 “Neo”,而对这个值的任何修改都将反映在这个位置。

要修改属性默认的特性,必须使用 Object.defineProperty() 方法。这个方法接收三个参数:属性所在的对象、属性的名字和一个描述符对象。其中,描述符对象的属性必须是:configurable、enumerable、writable 和 value。设置其中的一或多个值,可以修改对应的特性值。例如:

        var person = {
            name: "Neo",
            age: "30",
            job: "Software Engineer",
            sayName: function() {
                console.log(this.name);
            }
        };
        Object.defineProperty(person, "name", {
                                  writable: false,
                                  value: "Toby"
                              });

        person.sayName();
        person.name = "Neo";
        person.sayName();

输出结果:

JavaScript 理解对象 1 属性类型_第1张图片
输出结果

将 writable 设置为 false 表示只读。

类似地,将某个属性的可配置特性(configurable)设置为 false 的话,我们将无法删除对应的属性。例如:

        var person = {
            name: "Neo",
            age: "30",
            job: "Software Engineer",
            sayName: function() {
                console.log(this.name);
            }
        };
        Object.defineProperty(person, "name", {
                                  configurable: false,
                                  value: "Toby"
                              });

        person.sayName();
        delete person.name;
        person.sayName();

其输出结果为:

JavaScript 理解对象 1 属性类型_第2张图片
输出结果

而且,如果一旦我们将某个属性的可配置特性(configurable)设置为 false 的话,那么我们将不能再把它变回可配置的了。此时,再调用 Object.defineProperty() 方法修改除 writable 之外的特性,都会导致错误:

        var person = {
            name: "Neo",
            age: "30",
            job: "Software Engineer",
            sayName: function() {
                console.log(this.name);
            }
        };
        Object.defineProperty(person, "name", {
                                  configurable: false,
                                  value: "Toby"
                              });

        Object.defineProperty(person, "name", {
                                  configurable: true,
                                  value: "Toby"
                              });

上面的示例的输出结果如下:

JavaScript 理解对象 1 属性类型_第3张图片
输出结果

也就是说,可以多次调用 Object.defineProperty() 方法修改同一个属性,但在把 configurable 特性设置为 false 之后就会有限制了。

在调用 Object.defineProperty() 方法时,如果不指定,configurable、enumerable 和 writable 特性的默认值都是 false。

  1. 访问器属性

访问器属性有如下 4 个特性:

  • [[Configurable]]:表示能否通过 delete 删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性。默认值为 true。
  • [[Enumerable]]:表示能否通过 for-in 循环返回属性。默认值为 true。
  • [[Get]]:在读取属性时调用的函数。默认值为 undefined。
  • [[Set]]:在写入属性时调用的函数。默认值为 undefined。

访问器属性不能直接定义,必须使用 Object.defineProperty() 方法来定义:

        var book = {
            __year: 2014,
            edition: 1
        }
        Object.defineProperty(book, "year", {
                                  get: function() {
                                      return this.__year;
                                  },
                                  set: function(newValue) {
                                      if (newValue > 2014) {
                                          this.__year = newValue;
                                          this.edition += newValue - 2014;
                                      }
                                  }
                              });

        book.year = 2017;
        console.log(book.edition);

输出结果:

JavaScript 理解对象 1 属性类型_第4张图片
输出结果

如果我们不指定 setter 函数,那么这个属性就是只读的,写入就是无效的:

        var book = {
            __year: 2014,
            edition: 1
        }
        Object.defineProperty(book, "year", {
                                  get: function() {
                                      return this.__year;
                                  }
                              });

        book.year = 2017;
        console.log(book.edition);

输出结果:

JavaScript 理解对象 1 属性类型_第5张图片
输出结果

你可能感兴趣的:(JavaScript 理解对象 1 属性类型)