为什么 [[HomeObject]] 在方法的 shorthand 语法中不同?

Why [[HomeObject]] is different in shorthand syntax of method?

本题来源于

接受的答案是:

Because super is only valid inside methods.

但是在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());   

understanding es6 中,Nacholas 说:

Attempting to use super outside of concise methods results in a syntax error

Methods were just object properties that contained functions instead of data.

Any reference to super uses the [[HomeObject]] to determine what to do. The first step is to call Object.getPrototypeOf() on the [[HomeObject]] to retrieve a reference to the prototype. Then, the prototype is searched for a function with the same name. Last, the this binding is set and the method is called.

那么 [[HomeObject]] 似乎在 shorthand 方法的语法上有所不同?我很好奇为什么?

首先,MDN 不是官方 Javascript 文档。虽然它通常很有帮助,但它并不是与该语言相关的任何内容的权威来源。该官方规范将在 ECMAScript specification 中。这就是定义 Javascript 语法的地方。

在那份文件中,有一个叫做 MethodDefinition 的东西。有几种语法可用于方法定义。 greeting() {} 语法是一种可用于 MethodDefinition 的语法。 propName: function() {} 的典型对象文字 属性 定义不是。它是这样定义的:

然后,要查看 MethodDefinition 是什么,请转到 section 14.3.8,其中记录了 MethodDefinition 的步骤,如下所示:

在第 7 步中,它调用 MakeMethod()。如果您转到 that part of the specification,您将看到 [[HomeObject]] 值的设置位置。

因此,正如您已经发现 super 依赖于 [[HomeObject]] 的设置和细读规范,这是设置它的唯一方法。因此,要允许 super,它必须调用 MakeMethod() 并且调用 MakeMethod() 的唯一方法是使用上述语法之一和 [=47 的常规对象文字语法=]如propName: fn不是其中之一。

[[HomeObject]] 属性 是在 类 和常规对象的方法上定义的。但是对于对象,方法必须完全声明为method(),而不是“method: function()”。

我们没有区别,但是 JavaScript。

下面的示例使用了 not-method、property-function 语法。所以它没有[[HomeObject]],继承也不行:

 let animal = {
  eat: function(){ 
    console.log(this)
  }
};

let rabbit = {
  __proto__: animal,
  eat: function() {
    super.eat();
  }
};

rabbit.eat(); 

//调用super时出错(因为没有[[HomeObject]])

如上所述

[[HomeObject]] 值在 MakeMethod() 方法中设置,反过来,仅适用于适合该方法角色的函数,即函数声明为:

PropertyName ( StrictFormalParameters ) { FunctionBody } that part of the specification