JS面向对象-理解对象

本篇主要是「JavaScript高级程序设计-面向对象的程序设计」一章中第一篇「理解对象」回顾的笔记

属性类型

数据属性

数据属性包含一个数据值的位置,在这个位置可以读取和 写入值。它有4个特性:

  • [[Configureble]]
    • 作用
      • 表示能否通过delete删除属性
      • 表示能否修改属性的特性
      • 表示能否把属性修改为访问器属性
    • 默认值
      • true
  • [[Enumerable]]
    • 作用
      • 表示能否通过for-in循环返回属性
    • 默认值
      • true
  • [[Writable]]
    • 作用
      • 表示能否修改属性的值
    • 默认值
      • true
  • [[Value]]
    • 作用
      • 表示能否修改属性的值
    • 默认值
      • undefined

如要修改属性默认的特性,需要使用ES5defineProperty()方法,它接收3个参数:

  • 属性所在的对象
  • 属性的名字
  • 一个描述符对象
    • configurable
    • enumerable
    • writable
    • value

示例:

// writable 控制数据是否只读
var person = {};
Object.defineProperty(person, 'name', {
  writable: false,
  value: 'Nicholas'
});
console.log(person.name); // Nicholas
person.name = 'Greg';
console.log(person.name); // Nicholas

// configurable设置为false后就不能再修改
var person = {};
Object.defineProperty(person, 'name', {
  configurable: false,
  value: 'Nicholas'
});

var person = {};
Object.defineProperty(person, 'name', {
  configurable: true,
  value: 'Nicholas'
}); // 报错

访问器属性

访问器属性不包含数据值;它们包含一对gettersetter函数。读取时调用getter,写入时调用setter。访问器属性有4个特性:

  • [[Configureble]]

    • 作用
      • 表示能否通过delete删除属性
      • 表示能否修改属性的特性
      • 表示能否把属性修改为访问器属性
    • 默认值
      • true
  • [[Enumerable]]

    • 作用
      • 表示能否通过for-in循环返回属性
    • 默认值
      • true
  • [[Set]]

    • 作用
      • 在读取属性时调用的函数
    • 默认值
      • undefined
  • [[Get]]

    • 作用
      • 在写入属性时调用的函数
    • 默认值
      • undefined

示例:

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;
console.log(book.edition); // 12

定义多个属性

可以使用Object.defineProperties。示例:

var book = {};
Object.defineProperties(book, {
  _year: {
    value: 2004
  },
  edition: {
		value: 1
  },
  year: {
    get: function() {
      return this._year;
    },
    set: function() {
      if(newValue > 2004) {
        this._year = newValue;
        this.edition += newValue - 2004;
      }
    }
  }
});

读取属性的特性

使用Object.getOwnPropertyDescriptor(),可以取得给制定属性的描述符。

接收参数:

  • 属性所在对象
  • 要读取其描述符的属性名称

返回值:

  • 属性对象

示例:

var book = {};
Object.defineProperties(book, {
  _year: {
    value: 2004
  },
  edition: {
		value: 1
  },
  year: {
    get: function() {
      return this._year;
    },
    set: function() {
      if(newValue > 2004) {
        this._year = newValue;
        this.edition += newValue - 2004;
      }
    }
  }
});

var descriptor = Object.getOwnPropertyDescriptor(book, '_year');
console.log(descriptor.value); // 2004
console.log(descriptor.configurable); // false
console.log(typeof descriptor.get); // undefined

var descriptor = Object.getOwnPropertyDescriptor(book, 'year');
console.log(descriptor.value); // undefined
console.log(descriptor.enumerable); // false
console.log(typeof descriptor.get); // "function"