愿你坚持不懈,努力进步,进阶成自己理想的人

—— 2017.09, 写给3年后的自己

《Javascript高级程序设计》读书笔记——第6章(属性类型)

ECMA中有两种属性:数据属性访问器属性

一、数据属性

数据属性,其特性主要有:
1)[[Configurable]],表示一个属性是否可配置的,当这个值为true的时候,那么可以有以下行为:

  • 能够通过delete删除属性
  • 能够修改属性的特性
  • 能够把属性类型改为访问器属性类型

2)[[Enumerable]] 表示一个属性是否可枚举的:即能否通过for-in循环返回属性
3)[[Writable]] 表示能否修改一个属性的值
4)[[Value]] 数据值的存储位置

要修改这些特性,需要使用ES5中的Object.defineProperty()方法,这个方法接受三个参数,分别为:被修改属性所在的对象,被修改属性的名称,描述符对象
而其中描述符对象必须是configurablewritableenumerablevalue中的一或多个。
注意:在一个对象里直接定义的属性,其configurablewritableenumerable默认情况下都是true,而通过Object.defineProperty()定义的属性,默认情况下则都是false
以下进行试验,有:

var obj = {}
Object.defineProperty(obj, 'name', {
    value: 'RuphiLau'
});
obj.name; // 'RuphiLau'
obj.name = 'Ruphi';
obj.name; // 'RuphiLau'
Object.keys(obj); // []
delete obj.name; // false
obj.name; // 'RuphiLau'

一旦把一个属性的特性设置为不可配置的,那么它就再也不能变为可配置的了,这种情况下,再次调用Object.defineProperty()设置任何属性都会报错,如:

var obj = {}
Object.defineProperty(obj, 'name', {
    configurable: false,
    value: 'RuphiLau'
});
// 以下代码会报错
Object.defineProperty(obj, 'name', {
    value: '123'
});

而在configurabletrue的情况下,就可以多次调用来进行修改了


二、访问器属性

访问器属性不包含属性的值,它的主要特性有:
1)[[Configurable]]
2)[[Enumerable]]
3)[[Get]] 设置getter函数
4)[[Set]] 设置setter函数
访问器属性的特性需要通过Object.defineProperty()进行修改,而其中对于getter和setter,它们 内部的this指向属性所在的对象

IE8首先实现了Object.defineProperty(),但是IE8只是部分实现,它的使用带有以下的限制:只能在DOM对象上使用该方法,且只能创建访问器属性

还有两个非标准方法也可以实现getter和setter,这就是由火狐浏览器首先引入的__defineGetter__()__defineSetter__(),使用如:

var obj = {
    _birthYear: 1996
}
obj.__defineGetter__('age', function() {
    return (new Date()).getFullYear() - this._birthYear;
});
obj.__defineSetter__('age', function(newVal) {
    this._birthYear = (new Date()).getFullYear() - newVal;
});


三、定义多个属性

ES5还提供了Object.defineProperties()方法,用于一次性定义多个属性,如:

var obj = {};
Object.defineProperties(obj, {
    prop1: {
        // 描述符1
    },
    prop2: {
        // 描述符2
    }
    // ...
});


四、读取属性的特性

可以使用Object.getOwnPropertyDescriptor(obj, propName)方法来获取一个属性各项特性的设置情况。
对于数据属性,它返回的对象里包含有如下属性:

  • configurable
  • enumerable
  • writable
  • value

对于访问器属性,它返回的对象里包含有如下属性:

  • configurable
  • enumerable
  • get
  • set