ECMAScript 中有两种属性: 数据属性和访问器属性.
一, 数据属性
数据属性包含一个数据值的位置, 这个位置可以读取 / 写入数据值. 数据属性有四个描述其行为的特性.
a. Configurable: 表示能否通过 delete 删除属性从而重新定义属性, 能否修改属性特性, 能否把属性修改为访问器属性.
b. Enumerable: 表示能否通过 for-in 循环返回属性.
c. Writable: 表示能否修改属性值.
d. Value: 包含这个属性的数据值. 读取写入值在这个位置. 默认值为 undefined.
使用字面量方法定义对象属性, 它们的 Configurable/Enumerable/Writable 特性默认值为 true.
1. 修改属性特性: Object.defineProperty()
修改属性特性需要使用 Object.definProperty() 方法. 该方法接受三个参数: 属性所在对象, 属性名称, 一个描述符对象.
例如:
- var person = {};
- Object.defineProperty(person,'name',{
- writable:false,
- value:'Nicholas'
- });
- person.name;//'Nicholas'
- person.name = 'Greg';
- person.name;//'Nicholas'
Writable 特性设置为 false 表示这个属性是只读的, 不可以修改. 如果尝试为它指定新值, 非严格模式下, 赋值操作会被忽略; 严格模式下赋值操作会导致报错.
类似的把 configurable 设置为 false, 表示不能删除该属性. 如果对这个属性调用 delete, 非严格模式下会忽略 delete 操作, 严格模式下赋值操作会导致报错.
而且, 一旦把属性的 configurable 特性设置为 false, 就不可以在修改为 true. 此时再调用 Object.defineProperty() 方法修改除 writable 之外的特性都会导致错误.
再调用 Object.defineProperty() 时, 如果不指定 configurable/writable/enumerable
的值, 默认都为 false.
二, 访问器属性
访问器属性不包含数据值, 它们包含一对 getter 和 setter 函数 (这个函数不是必需的).
在读取访问器属性时会调用 getter 函数, 这个函数负责返回有效的值; 在写入访问器属性时, 会调用 setter 函数并传入值, 这个函数负责决定如何处理数据.
访问器属性的特性:
a.Configurable: 表示能否通过 delete 删除属性而重新定义属性, 能否修改属性特性, 能否把属性修改为数据属性. 字面量定义的对象属性, 该特性默认值为 true.
b.Enumerable: 表示能否通过 for-in 循环返回属性. 字面量定义的对象属性, 该特性默认值为 true.
c. Get: 读取属性时调用的函数, 默认值为 undefined
d. Set: 写入属性时调用的函数, 默认值为 undefined
1. 定义访问器属性
访问器属性不能直接定义, 必须使用 Object.definProperty() 来定义.
- var book = {
- _year:2018,
- edition:1
- };
- Object.defineProperty(book,'year',{
- get: function () {
- return this._year;
- },
- set:function (newValue) {
- if (newValue> 2018) {
- this._year = newValue;
- this.edition += newValue - 2018;
- }
- }
- });
- book.year = 2019;
- alert(book.edition);//2
- alert(book._year);//2019
book 对象的 year 属性就是访问器属性, 包含一个 getter 和 setter 函数. getter 函数返回_year 的值, setter 函数通过计算来确定正确的版本.
不一定非要同时指定 getter 和 setter. 只指定 getter 意味着属性不能写, 尝试写入属性会被忽略. 在严格模式下, 尝试写入只指定了 getter 函数的属性会抛出错误. 类似的只指定 setter 函数的属性不能读, 在非严格模式下会返回 undefined.
三, 定义多个属性: Object.defineProperties()
Object.defineProperties() 方法接受两个对象参数: 第一个对象是要添加或修改其属性的对象, 第二对象的属性与第一个对象中要添加或修改的属性一一对应.
例如:
- var book = {};
- Object.defineProperties(book, {
- _year: {
- value: 2018
- },
- edition: {
- value: 1
- },
- year: {
- get: function () {
- return this._year;
- },
- set: function (newValue) {
- if (newValue> 2018) {
- this._year = newValue;
- this.edition = newValue - 2018;
- }
- }
- }
- });
四, 读取属性的特性 Object.getOwnPropertyDescriptor()
Object.getOwnPropertyDescriptor() 方法可以获取给定属性的描述符. 该方法接受两个参数: 属性所在的对象, 需要读取描述符的属性名. 返回值是一个对象, 如果这个属性是数据属性, 那么这个对象的属性有 configurable,enumerable,writable,value; 如果这个属性是一个访问器属性, 那么这个对象的属性有 configurable,enumerable,set,get.
- var book = {};
- Object.defineProperties(book, {
- _year: {
- value: 2018
- },
- edition: {
- value: 1
- },
- year: {
- get: function () {
- return this._year;
- },
- set: function (newValue) {
- if (newValue> 2018) {
- this._year = newValue;
- this.edition = newValue - 2018;
- }
- }
- }
- });
- var descriptor = Object.getOwnPropertyDescriptor(book, '_year');
- alert(descriptor.value);//2018
- alert(descriptor.configurable);//false
- alert(descriptor.get);//undefined
- var descriptor1 = Object.getOwnPropertyDescriptor(book, 'year');
- alert(descriptor1.value);//undefined
- alert(descriptor1.enumerable);//false
- alert(descriptor1.get);//function(){return this._year;}
来源: http://www.qdfuns.com/article/46690/0edc6c36ddf4ac97cc4e65bc5da3bcaf.html