Skip to content

Latest commit

 

History

History
78 lines (63 loc) · 3.63 KB

【第26期】对象属性的特性.md

File metadata and controls

78 lines (63 loc) · 3.63 KB

之前曾经简单总结过js中的对象,见“【第24期】浅析js中的类和对象”。

从数据结构的层面去理解,完全可以将“对象”理解为一组没有顺序名值对。但是因为js中没有“类”的概念,传统编程语言中类有属性和方法,而且其属性方法可以通过publicprivate等修饰符进行修饰,这样不仅可以灵活的控制类属性和方法的访问,但是针对类的实例——对象而言,并没有类似的方式可以进行控制。

但是在js中,对象的属性可以通过“特性”来设置,或者来控制外界对其的访问(包括读和写)。

ECMA-262第5版在定义只有内部才用的特性(attribute)时,描述了属性(property)的各种特征。

对象的属性可以分为两类:数据属性访问器属性。不同类的属性分别会有不同的描述特征。

  • 数据属性
  • 访问器属性

数据属性

“数据属性”包含一个数据值的位置,在这个位置可以读取和写入值。是可读取和写入值的属性。

“数据属性”有4个描述其行为的特性:

  • [[Configurable]]:表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性。
  • [[Enumerable]]:表示能否通过for-in循环返回属性。
  • [[Writable]]:表示能否修改属性的值。
  • [[Value]]:包含这个属性的数据值。
    • 读取属性值的时候,从这个位置读;
    • 写入属性值的时候,把新值保存在这个位置。

访问器属性

“访问器属性”不包含数据值,包含一对儿getter和setter函数(不过,这两个函数都不是必需的)。

只要设置或检索属性值,“访问器属性”就会调用用户提供的函数:

  • 在读取访问器属性时,会调用getter函数,这个函数负责返回有效的值
  • 在写入访问器属性时,会调用setter函数,并传入新值,这个函数负责决定如何处理数据。

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

  • [[Configurable]]:表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为数据属性。
  • [[Enumerable]]:表示能否通过for-in循环返回属性。
  • [[Get]]:在读取属性时调用的函数。
  • [[Set]]:在写入属性时调用的函数。
var book = {
    _year: 2004,
    edition: 1
};
Object.defineProperty(book, "year", {
    get: function(){
        return this._year;
    },
    set: function(newValue){
        if (newValue > 2004) {
            this._year = newValue;
            this.edition += newValue - 2004;
        }
    }
});
book.year = 2005;
alert(book.edition); //2

属性的定义

“数据属性”可以直接定义,但“访问器属性”不能直接定义,必须使用Object.defineProperty()来定义(也可以定义数据属性)。

属性的使用

也许对“访问器属性”怎么使用很困惑,但是从上面代码可以看出,其实对属性的读/写方法并无差别,只是 内部的处理逻辑不同

相关操作和方法

在读取和写入属性值时,会受到属性特性的影响。相关的方法有:

  • Object.defineProperty():定义属性
  • Object.defineProperies():定义多个属性
  • in运算符
  • Object.prototype.hasOwnProperty()
  • Object.getOwnPropertyDescriptor():读取属性的特性
  • getOwnPropertyNames()
  • Object.keys()
  • for-in循环

参考资料

(本篇完)