Почему [[HomeObject]] отличается сокращенным синтаксисом метода?

Этот вопрос получен из супер ключевого слова неожиданно здесь

В принятом ответе говорится:

Потому что super действует только внутри методов.

Но в MDN кажется, что эти два оба метода:

let person = {
    greeting() {
        return "Hello";
    }
};

let friend = {
    // shorter syntax for method?
    greeting() {
        return super.greeting() + ", hi!";
    }

//  method?
//  greeting: function() {
//      return super.greeting() + ", hi!"; // Throw error: Uncaught SyntaxError: 'super' keyword unexpected here
//  }

};

Object.setPrototypeOf(friend, person);
console.log(friend.greeting());   

В понимании es6, Начолас говорит:

Попытка использовать super вне кратких методов приводит к синтаксической ошибке

Methods были просто свойствами объекта, которые содержали функции вместо данных.

Любая ссылка на super использует [[HomeObject]], чтобы определить, что делать. Первый шаг - вызвать Object.getPrototypeOf () для [[HomeObject]], чтобы получить ссылку на прототип. Затем в прототипе ищется функция с таким же именем. Наконец, устанавливается привязка this и вызывается метод.

Кажется, что [[HomeObject]] отличается сокращенным синтаксисом метода? Мне любопытно, почему?


person Tina Chen    schedule 04.07.2018    source источник
comment
Можете ли вы показать содержащий контекст для ваших двух блоков кода? Что это внутри? greet: function() {}, что просто объявление свойства для нормального объекта, вероятно, технически не является методом, насколько super это касается. Это просто собственность. В любом случае, почему бы просто не использовать синтаксис class и избежать всей проблемы. Вам уже требуется super, чтобы быть доступным, так что вы не можете рассчитывать на class.   -  person jfriend00    schedule 04.07.2018
comment
Спасибо @ jfriend00, 1. блоки кода завершены. 2. в MDN greet: function() {} кажется удовлетворяет method определению? Вот что меня смущает. 3. Синтаксис class - это другая тема, я просто смотрю книгу и интересуюсь поведением super.   -  person Tina Chen    schedule 04.07.2018
comment
Ну, super() предназначен для использования с class. Если вы его используете именно здесь, то вам не нужно разгадывать ни одной из этих головоломок.   -  person jfriend00    schedule 04.07.2018
comment
В MDN super # Использование super.prop в объектных литералах, есть также пример использования super в инициализаторе объекта / буквальной нотации   -  person Tina Chen    schedule 04.07.2018
comment
И обратите внимание, что в этих примерах литералов объектов используется ТОЛЬКО синтаксис метода ярлыков. Похоже, в этом синтаксисе есть что-то особенное.   -  person jfriend00    schedule 04.07.2018
comment
@ jfriend00 Да, вот что я хочу спросить: что особенного в этом синтаксисе ?? Это не задокументировано. Кстати, я не буду использовать super в литерале объекта, спасибо.   -  person Tina Chen    schedule 04.07.2018
comment
Сейчас у меня нет сил пытаться следовать сложной паутине синтаксиса в спецификации EMCASCript, но это _ 1_ вызов, который устанавливает [[HomeObject]] и затем разрешает использование super. Вам нужно будет проследить цепочку определений синтаксиса, чтобы точно узнать, какой синтаксис делает и не приводит к MakeMethod() вызову или не вызову. MDN не является источником документации - источником является спецификация EMCAScript.   -  person jfriend00    schedule 04.07.2018
comment
Похоже, это здесь: ecma-international.org/ecma -262 / 6.0 / # sec-object-initializer. Только сокращенный синтаксис является MethodDefinition (который имеет супер возможности). Обычный синтаксис свойства - это просто свойство, а не метод в том виде, в каком Javascript определяет и инициализирует то, что он вызывает метод.   -  person jfriend00    schedule 04.07.2018


Ответы (1)


Во-первых, MDN не является официальной документацией Javascript. Хотя это часто бывает полезно, это не исчерпывающий источник чего-либо, связанного с языком. Эта официальная спецификация будет находиться в спецификации ECMAScript. Вот где определяется грамматика Javascript.

В этом документе есть что-то, что называется MethodDefinition . Есть несколько синтаксисов, которые можно использовать для определения метода. Синтаксис greeting() {} - это один из таких синтаксисов, который можно использовать для MethodDefinition. Типичное определение свойства литерала объекта propName: function() {} - нет. Вот как это определяется:

введите описание изображения здесь

Затем, чтобы узнать, что такое MethodDefinition, перейдите на страницу раздел 14.3.8, где описаны шаги для MethodDefinition следующим образом:

введите описание изображения здесь

На шаге 7 он вызывает MakeMethod(). Если вы перейдете к этой части спецификации, вы посмотрите, где устанавливается значение [[HomeObject]].

введите описание изображения здесь

Итак, как вы уже выяснили, super полагается на установку [[HomeObject]] и внимательное изучение спецификации, это единственный способ ее установки. Итак, чтобы super было разрешено, он должен вызвать MakeMethod(), и единственный способ вызова MakeMethod() - это один из приведенных выше синтаксисов, и обычный синтаксис литерала объекта для свойства, такого как propName: fn, не является одним из них.

person jfriend00    schedule 04.07.2018
comment
Это так интересно для меня, если функция, объявленная не как метод, как свойство, имеет значение, функция, какой процесс произошел. Какая часть объясняет этот процесс в спессификации. - person Murad Sofiyev; 26.09.2019
comment
@MuradSofiyev - Я не понимаю о чем вы. - person jfriend00; 26.09.2019