给JS对象设置“计算属性”

2,110 阅读1分钟

在定义对象时,如果有个属性是由其他属性拼接或计算而来的,应该如何定义这个属性呢?你可能想到了这种写法:

var obj = {
  a: 18,
  b: "my age is ",
  c: this.b + this.a,
};
console.log(obj.c);

希望输出 my age is 18 但是实际上输出 NaN,为什么呢?因为 this 指代的是全局,那怎样得到想要的结果呢?用下面的方法:

var obj = {
  a: 18,
  b: "my age is ",
  c: function () {
    return this.b + this.a;
  },
}
console.log(obj.c());

此时的 this 就是指 obj 本身了,但是 c 是个方法,不是属性,所以要这样子写:

var obj = {
  a: 18,
  b: 'my age is ',
  get c() {
    return this.b + this.a;
  }
}
console.log(obj.c)

这里的 c 不再是函数了,而是访问器属性,本质上是 Object.defineProperty 的语法糖,可以让我们像访问普通属性一样去访问 c,而不再是调用 c 方法,使用起来更加优雅。下面两种写法是等价的:

通过对象初始化器:

const user = {
  firstName: 'John',
  lastName: 'Smith',
  get fullName() {
    return `${this.name} ${this.surname}`
  },

  set fullName(value) {
    ;[this.name, this.surname] = value.split(' ')
  },
}

使用 Object.defineProperty :

const user = {
  firstName: 'John',
  lastName: 'Smith'
}
Object.defineProperty(user, 'fullName', {
  enumerable: true,
  configurable: true,
  get() {
    return `${this.firstName} ${this.lastName}`
  },
  set(value) {
    ;[this.firstName, this.lastName] = value.split(' ')
  },
})