无法访问深层嵌套对象属性,而不会出现只读错误

时间:2019-04-25 08:28:28

标签: javascript spread

每次尝试访问一个深层属性(我想通过它的索引猜测数组中的一个项目)时,都会出现以下错误:

  

错误TypeError:无法分配为只读对象'[object Object]'的属性'value'

找到下面我想运行的代码,但会在上面抛出错误:

@Input() data: CivilLiabilityQuestionnaireModel;
public questions: CivilLiabilityQuestionnaireModel;

this.questions = { ...this.data };

const questionGroupIndex = 0;
const questionGroupItemIndex = 0;

this.questions
    .questionGroup[questionGroupIndex]
    .questionGroupItems[questionGroupItemIndex]
    .answers[0]
    .value = form[val];

可能的更多细节:

// This works
this.questions.id = 'hotdog';

// This doesn't work
// ERROR TypeError: Cannot assign to read only property 'id' of object '[object Object]'
this.questions.questionGroup[questionGroupIndex].id = 'hamburger';

我以为只有使用散布运算符才能做到这一点,但这会将我所有的数组变成对象,而我需要不惜一切代价保持我的数组。

这是我尝试过的传播解决方案:

this.questions = {
  ...this.questions,
  questionGroup: {
    ...this.questions.questionGroup,
    [questionGroupIndex]: {
      ...this.questions.questionGroup[questionGroupIndex],
      questionGroupItems: {
        ...this.questions.questionGroup[questionGroupIndex].questionGroupItems,
        [questionGroupItemIndex]: {
          ...this.questions.questionGroup[questionGroupIndex].questionGroupItems[questionGroupItemIndex],
          answers: {
            ...this.questions.questionGroup[questionGroupIndex].questionGroupItems[questionGroupItemIndex].answers,
            [0]: {
              ...this.questions.questionGroup[questionGroupIndex].questionGroupItems[questionGroupItemIndex].answers[0],
              value: form[val]
            }
          }
        }
      }
    }
  }
};

2 个答案:

答案 0 :(得分:0)

也许您在某处将某个内容定义为constant,而您正在尝试对其进行更改。 Javascript自然不支持只读属性,因此基本上在实践中出现此错误的唯一原因是您将某个变量/属性定义为constant或将obj的属性定义为writable=false试图改变它。寻找questionGroupIndexquestionGroupItemIndex,您可能想更改它们。无论哪种方式,问题都不在嵌套中。

答案 1 :(得分:0)

我设法找到了解决问题的办法。 在原始问题的示例中,我做了以下事情:

this.questions = { ...this.data };

解决方案来自另一篇文章:https://stackoverflow.com/a/40922716/2664414

上述示例的问题在于,您仅克隆根属性,而嵌套的子属性保持冻结状态。

由于我的价值来自NGRX商店,因此基本上处于“冻结”状态,无法进行调整。

要解决此问题,您可以使用lodash中的cloneDeep()来确保嵌套属性也被克隆并丢失“冻结”状态。

this.questions = _.cloneDeep(this.data);