Как мне ссылаться на одни и те же свойства объекта во время его создания?

Я пытаюсь сделать что-то вроде

o = {
  a: { foo: 42 },
  b: o.a
}

Но это возвращает ошибку, о которой не указано. Я знаю, что смогу позже сделать o.b = o.a. Но мне интересно, можно ли определить b, пока я определяю o.

Ответы

Ответ 1

Это невозможно.

Объект не связан ни в какой области видимости выражений EcmaScript, когда оцениваются значения свойств.

Раздел 11.1.5 спецификации языка EcmaScript объясняет, как работает синтаксис конструктора объектов.

Далее описывается, как объект создается как побочный эффект оценки первой пары значений ключа свойства

Произведение PropertyNameAndValueList : PropertyAssignment оценивается следующим образом:

  • Пусть obj является результатом создания нового объекта, как если бы выражение new Object(), где Object - стандартный встроенный конструктор с этим именем.
  • Пусть propId будет результатом оценки PropertyAssignment.
  • Вызвать внутренний метод [[DefineOwnProperty]] obj с аргументами propId.name, propId.descriptor и false.
  • Возврат obj.

Обратите внимание, что PropertyAssignment оценивается после создания obj, но obj никогда не привязывается к любому имени, доступному для выражения EcmaScript.

Только после того, как все значения свойств будут оцениваться, все будет назначено на o или любой другой символ в вашей программе.

Ответ 2

Как @RobG прокомментировал — нет, вы не можете.

Однако вы можете использовать ключевое слово this внутри функций, определенных как свойства объекта, например:

o = {
  a: { foo: 42 },
  b: function () {
      return this.a;
  }
}

console.log(o.b()); // {foo: 42};

Ответ 3

Сейчас это только древняя история, но я только что узнал о getters and setters, которые идеально подходят для вашей ситуации, и я уверенные люди, смотрящие на этот вопрос, могут получить от него какую-то ценность.

o = {
  a: { foo: 42 },
  get b() {
    return this.a
    }
  }

console.log(o.b) // => { foo: 42 }

Ответ 4

Еще один способ сделать это:

(function() {
    var some = { foo: 42 };
    window.o = {
        a: some,
        b: some
    };
})();

alert(o.b.foo);

Ответ 5

o = {};
o.a = {foo: 42};
o.b = o.a;