在JavaScript中更新嵌套对象属性

时间:2019-09-10 17:02:56

标签: javascript ecmascript-6 es6-class

我下面有以下代码:

class Set {
  constructor() {
    console.log("New Set!");
  }

  get repsCompleted() {
    return this._repsCompleted;
  }

  set repsCompleted(value) {
    this._repsCompleted = value;
  }
}

class Exercise {
  constructor(name) {
    console.log(name);
    this.name = name;
  }

  get sets() {
    return [new Set(), new Set(), new Set()]
  }
}

let barbellSquat = new Exercise("Barbell Squat");
let updatedBarbellSquat = updateRepsCompleted(barbellSquat);

console.log(updatedBarbellSquat);

function updateRepsCompleted(exercise) {
  for (var i = 0; i < exercise.sets.length; i++) {
    exercise.sets[i].repsCompleted = 5;
  }

  return exercise;
}

我有一个课堂练习,其中有一个属性集,它是Set类型的对象的数组。

因此,我在Exercise类上创建了一个新对象,然后将该对象传递给一个函数,该函数的目的是更新设置的对象并将属性“ repsCompleted”设置为5。

然后我在console.log运动对象中,只是发现repsCompleted是未定义的。我不知道为什么。

在这里摆弄代码:

https://jsfiddle.net/the_archer/a09tpr63/10/

1 个答案:

答案 0 :(得分:1)

您不应该为sets使用吸气剂。每次读取或分配相应的属性时,都会使用getter或setter,以允许您自定义属性的工作方式。不仅是在第一次访问该属性时使用吸气剂。

因此,每次使用exercise.sets时,它都会创建一个包含3个空Set对象的新数组。 sets应该是普通属性,以便您每次都可以检索相同的值。您可以在构造函数中对其进行初始化。

如果您想隐藏sets属性,就像在repsCompleted类中使用Set一样,可以使用相同的方法:为实际属性使用不同的名称,并定义访问它的getter和setter。您还可以通过检查属性是否已设置来懒惰地对其进行初始化。

class Set {
  constructor() {
    console.log("New Set!");
  }

  get repsCompleted() {
    return this._repsCompleted;
  }

  set repsCompleted(value) {
    this._repsCompleted = value;
  }
}

class Exercise{
  constructor(name) {
    this.name = name;
    this._sets = null;
  }
  
  get sets() {
    if (!this._sets) {
      this._sets = [new Set(), new Set(), new Set()];
    }
    return this._sets;
  }
  
  set sets(value) {
    this._sets = value;
  }
}

let barbellSquat = new Exercise("Barbell Squat");
let updatedBarbellSquat = updateRepsCompleted(barbellSquat);

console.log(updatedBarbellSquat);

function updateRepsCompleted(exercise) {
  for (var i = 0; i < exercise.sets.length; i++) {
    exercise.sets[i].repsCompleted = 5;
  }

  return exercise;
}