是"目标"和"接收器" ES2015规范中的同义词?

时间:2016-06-05 17:00:45

标签: javascript

"接收者"和"目标"在ES2015规范(参见下面的示例)和Web上的其他地方使用,以引用用作this值的对象。

这些词是同义词还是它们有微妙的不同含义?

在调用时是否有一个正确的术语来引用函数的this值?

我注意到26.1.6Reflect.get的签名使用了表示意义差异的两个词。

这个问题源于ES2015规范中术语的不一致性。

规范用法示例:

表5,第7行([[Get]]),第6.1.7.2部分(我的大胆):

  

从中返回其键为propertyKey的属性的值   宾语。如果必须执行任何ECMAScript代码来检索   属性值,接收器在评估时用作此值   代码。

第2段,6.1.7.2部分(我的大胆):

  

内部方法名称是多态的。这意味着不同   当共同内部时,对象值可以执行不同的算法   方法名称被调用。那个实际的对象   调用内部方法是调用的“目标”。如果,在   运行时,算法的实现尝试使用   对象不支持的对象的内部方法,a   抛出TypeError异常。

2 个答案:

答案 0 :(得分:9)

回顾一下:

  • 对对象内部方法的每次调用都有一个“目标”,即调用的对象。

  • “Receiver”是[[Get]]方法的2 nd 参数,[[Set]]方法的3 rd

  • 其他internal object methods没有此额外参数。

那么,为什么[[Get]][[Set]]有接收者? 因为不是目标。

Receiver用于在[[Get]] / [[Set]]范围内调用getter和setter。

ES6 9.1.8

  1. 您致电A.Get( 'property', A )
  2. 如果A没有'属性',则调用A.prototype.Get( 'property', A )
    1. 目标现在是“A.prototype”。但接收者仍然是“A”。
    2. 如果A.prototype具有'property'的getter函数,它将使用Receiver A而不是目标A.prototype调用。
  3.   

    请注意,ES5的[[Get]](8.12.3)以不同的方式执行相同操作且没有Receiver,部分原因是原型攀爬发生在另一部分(8.12.2)。

    接收者仅存在于[[Get]]和[[Set]]的上下文中,其目的与目标不同。

    • 当[[Get]]需要引用其目标时,它使用O.
      对于[[Get]]的每次递归调用,当它爬上原型链时,O是不同的。

    • 接收器与[[Get]]爬上原型链相同。 它的作为参数传递给getter,接下来发生的事情不再与Receiver在同一范围内。

      

    O和Receiver 可能引用同一个对象,但在[[Get]]或[[Set]]的上下文中无关紧要。   实际上,Reflect.get允许调用者设置不同的目标和Receiver,并使它们与get get不同。

    对于其他内部对象方法,大多数方法根本不会爬上原型链。执行([[HasProperty]][[Enumerate]])的两个人不需要保留初始目标(可以这么说)。

    随着问题的解决,你then ask规范是否给出了“Receiver”在一般JavaScript讨论中使用的含义,就像它在6.1.7.2中定义“target”一样。 这个答案是否定的。

    1. “Receiver”的范围非常狭窄,仅用作参数名称,但“目标”以一般的,不太正式的方式使用。

    2. “目标”是从一般性讨论中借用的术语 - ES5没有定义调用目标的概念。 ES5“target”可以是参数,变量,语句,表达式或被调用函数。但不是this的隐含替代。

    3. 编写规范是为了以非常非常精确的方式传达“JavaScript行为”,使其非常技术化,包括使用参数。 它只是提供与一般编程讨论不同的沟通。

      3.A。许多JS开发人员根本不阅读规范。    它不需要日常编码。

      3.B。我们谈论“封闭”,“范围链”,“事件队列”,“胖箭”或“lambda”,不是吗? 规范没有定义这些术语。

      3.C。 规范可能以不同的名称命名,如执行上下文或作业队列 它可能根本就没有命名。关闭是一种紧急行为 当它确实命名时,它不会创建别名。箭头函数永远不会被称为lambda。

    4. 该规范并未规范一般性讨论。
      使用常识进行共同讨论。

答案 1 :(得分:0)

这可能无法回答问题。但这里是..

术语接收器源自OOP设计,其中一切都被抽象为对象。程序的执行主要包括对象之间的通信。对象通过调用彼此的方法相互通信。因此,被调用的对象接收一条消息。因此这个术语。

然而,语法已经扩展到在某种意义上有“对象”但不完全是 OOP 的语言/上下文。许多语言利用语法 MYVAR 通过某个对象/范围调用函数/方法的便利性,并且仍然将 some_object.some_method() 称为接收者。通常在函数/方法定义中称为 some_objectthis 或只是第一个参数或其组合。 JavaScript 更进一步,允许动态绑定 self。虽然实际上被调用的对象没有接收任何东西,语法只是隐式使用对象作为被调用函数的参数之一的糖。