6.1.1.2 属性类型之访问器属性

  访问器属性不包含数据值;它们包含一对getter和setter函数(不过,这两个函数都不是必须的)。在读取访问器属性时,会调用getter函数,这个函数负责返回有效的值;在写入访问器属性时,会调用setter函数并传入新值,这个函数负责决定如何处理数据。访问器属性有如下4个特性。

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

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

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

  以上代码创建了一个book对象,并给它定义两个默认的属性:_year和edition。_year前面的下划线是一种常用的记号,用于表示只能通过对象方法访问的属性。而访问器属性year则包含一个getter函数和一个setter函数。getter函数返回_year的值,setter函数通过计算来确定正确的版本。因此,把year属性修改为2005会导致_year变成2005,而edition变为2。这是使用访问器属性的常见方式,即设置一个属性的值会导致其他属性发生变化。

  不一定非要同时制定getter和setter。只指定getter意味着属性不能写,尝试写入属性会被忽略。在严格模式下,尝试写入只指定了getter函数的属性会抛出错误。类似的,只指定setter函数的属性也不能读,否则在非严格模式下会返回undefined,而在严格模式下会抛出错误。

  支持ECMAScript 5的这个方法的浏览器有IE9+(IE8只是部分实现)、FF4+、Safari5+、Opera12+和Chrome。在这个方法之前,要创建访问器属性,一般都使用两个标准的方法:_defineGetter_()和_defineSetter_()。这两个方法最初是由Firefox引入的,后来Safari3、Chrome1和Opera9.5也给出了相同的实现。使用这两个遗留的方法,可以像下面这样重写前面的例子。

var book ={
    _year=2004,
    edition:1
};

//定义访问器的旧方法
book._defineGetter_("year",function(){
    return this._year;
});

book._defineSetter_("year",function(){
    if(newValue>2004){
        this._year = newValue;
        this.edition += newValue - 2004;
    }
});

book.year=2005;
alert(book.edition);//2

  在不支持Object.defineProperty()方法的浏览器中不能修改[[Configurable]]和[[Enumerable]]。

原文地址:https://www.cnblogs.com/yxlove/p/4558174.html