You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

咨询:JavaScript对象初始化时引用自身属性为何报错?

为什么var obj={'A':'B','C':obj['A']};会报错?

兄弟,这个问题本质是JavaScript对象字面量的执行时序在搞事情,咱们一步步拆解清楚:

核心原因:对象还没赋值给obj,就提前引用了obj

当你写var obj = { ... }的时候,整个过程是分两步的:

  1. JS引擎先在内存里创建一个空对象,然后按顺序处理大括号里的每个属性(把键值对逐个添加到这个空对象上)。
  2. 只有当所有属性都处理完、对象完全构建好之后,才会把这个对象赋值给obj变量。

所以在处理C: obj['A']这行代码时,obj变量还没有指向正在构建的这个对象——它此时要么是undefined(如果是第一次声明obj),要么是之前的旧值。这时候你去取obj['A'],自然会得到undefined,甚至直接报错。

你的测试代码为啥先打印B、A再报错?

看你写的测试代码:

var f=function(str){ console.log(str); return str; };
var obj={ [f('A')]:[f('B')], "C":obj['A'] };

这里的执行顺序是:

  1. 处理第一个属性[f('A')]:[f('B')]
    • 先计算属性名:执行f('A'),打印A,返回字符串'A'作为键。
    • 再计算属性值:执行f('B'),打印B,返回数组['B']作为值。
    • 'A': ['B']添加到正在构建的对象上。
  2. 然后处理第二个属性"C":obj['A']
    • 计算属性值时引用obj['A'],但此时obj还没被赋值为刚才的对象,所以objundefined,访问undefined['A']直接报错。

你说先打印B、A,可能是代码里写反了f('A')f('B')的位置,但不管顺序如何,核心问题都是obj还没指向当前对象就被引用了。

解决方法

根据你的需求,有几种靠谱的方案:

方案1:先创建对象,再补加C属性

最直接的方式,等对象完全赋值给obj后,再给C赋值:

var obj = {
  'A': 'some complex function returns a string'
};
obj.C = obj.A; // 或者 obj['C'] = obj['A']

方案2:用getter实现动态同步(如果需要C跟随A变化)

如果希望C的值能自动跟着A更新,可以用对象的getter方法:

var obj = {
  'A': 'some complex function returns a string',
  get C() {
    return this.A; // 这里的this指向当前对象,没问题
  }
};
// 之后修改obj.A,obj.C也会自动变化
obj.A = 'new value';
console.log(obj.C); // 输出 'new value'

方案3:提前把A的值存到变量里

如果只是一次性复制,不想后续同步,可以先把A的计算结果存到变量中,再给对象的两个属性赋值:

const aValue = 'some complex function returns a string';
var obj = {
  'A': aValue,
  'C': aValue
};

内容的提问来源于stack exchange,提问作者ocomfd

火山引擎 最新活动