一、理解对象

  1. let person = {
  2. name: "limengxiao",
  3. age: "30",
  4. job: "前端开发工程师"
  5. sayName() {
  6. console.log("我的名字叫" + this.name);
  7. }
  8. }

这是通常的对象自变量定义对象的方法。该对象中每个属性都有自己的特征,而这些特征决定了,他们在javascript中的行为。

1.1、属性的类型

ECMA-262使用一些内部特性来描述属性的特征。这些特性是由为JavaScript实现引擎的规范定义的。因此,开发者不能在JavaScript中直接访问这些特性。为了将某个特性标识为内部特性,规范会用两个中括号把特性的名称括起来,比如[[Enumerable]]。
属性氛围两种:数据属性和访问器属性。

1、数据属性

数据属性包含一个保存数据值的位置。值会从这个位置读取,也会写入到这个位置。
数据属性有四个特性描述它们的行为:

  • [[Configurable]]
  • [[Enumerable]]
  • [[Writable]]
  • [[Value]]

要修改属性的默认特性,必须使用Object.defineProperty。这个方法接受三个参数:要给其添加属性的对象、属性的名称和一个描述符对象。例如:

  1. let person = {}
  2. Object.defineProperty(person, name, {
  3. writable: false,
  4. value: "limengxiao"
  5. })
  6. console.log(person.name) //limengxiao
  7. person.name = "anthor"
  8. console.log(person.name) //limengxiao

只读的属性,在非严格模式下尝试给这个属性重新赋值会被忽略。在严格模式下,尝试修改只读属性的值会抛出错误。
PS:一个对象属性被定义成不可配置的之后,就不能变成可配置的了,在严格模式下也会抛错。
多数情况下,可能都不需要Object.defineProperty()提供的这些强大的设置,但要理解JavaScript对象,就要理解这些概念。

2、访问器属性

访问器属性不包含数据值。相反它包含一个获取(getter)函数,和设置(setter)函数,不过这两个函数不是必须的。
访问器属性有四个特性描述他们的行为:

  • [[Configurable]]
  • [[Enumerable]]
  • [[Get]]
  • [[Set]]

访问器属性是不能并直接定义的,必须通过Object.defineProperty()定义。

  1. // 定一个对象包含伪私有成员year_和公共成员edition
  2. let book = {
  3. year_: 2017,
  4. edition: 1
  5. }
  6. Object.defineProperty(book, "year", {
  7. get() {
  8. return this.year_;
  9. }
  10. set(newValue) {
  11. if(newValue > 2017) {
  12. this.year_ = newValue;
  13. this.edition = newValue - 2017;
  14. }
  15. }
  16. })
  17. book.year = 2018;
  18. console.log(book.edition) // 2

解析:year中的下划线常用来表示该属性并不希望在对象方法的外部被访问。另一个属性year被定义为一个访问器属性,其中获取函数简单地返回year的值,而设置函数会做一些计算以决定正确的版本(edition)