【问题标题】:What does ReturnIfAbrupt mean in ES6 draft?ReturnIfAbrupt 在 ES6 草案中是什么意思?
【发布时间】:2012-10-11 07:48:53
【问题描述】:

我目前正在为 ES6 草案实施一些填充程序。我想知道是否有人可以告诉我ReturnIfAbrupt 的含义。例如,我对Number.toInt 的实现(调用内部[[ToInteger]] 如下:

if (!('toInt' in Number))
    Object.defineProperty(Number, 'toInt', {

        value: function toInt(value) {
            // ECMA-262 Ed. 6, 9-27-12. 9.1.4

            // 1. Let number be the result of calling ToNumber on the input argument.
            var number = Number(value);

            // 2. ReturnIfAbrupt(number).
            // ?

            // 3. If number is NaN, return +0.
            if (number != number) return 0;

            // 4. If number is +0, -0, +Infinity, or -Infinity, return number.
            if (number == 0 || 1 / number == 0) return number;

            // 5. Return the result of computing sign(number) * floor(abs(number)).
            return (n < 0 ? -1 : 1) * Math.floor(Math.abs(number));

        },

        writable: true,
        configurable: true

    });

第 2 步是ReturnIfAbrupt(number)。您会注意到我目前有 // ? 用于该步骤,因为我不确定该怎么做。 ReturnIfAbrupt(...) 是什么意思?

我已阅读草稿中关于 ReturnIfAbrupt 的部分,但是我无法理解第 2 步应该做什么做什么,在上面的代码中用什么代替 // ?

根据我的阅读,可能什么都不应该做,ReturnIfAbrupt 步骤仅仅意味着让 ToNumber 中发生的任何错误向上传播,退出函数。但是,这似乎过于冗长,因为我认为这是不言而喻的。此外,在我看来,ToNumber 甚至不会引发错误。有人可以确认或帮助我理解真正的含义吗?

【问题讨论】:

  • 是的,我已经读过了。这对我来说并不完全有意义,但从我能理解的情况来看,在这一步听起来我真的没什么可做的,如果ToNumber 在步骤 1 中抛出错误,它应该传播并且函数应该退出。但是,我真的不明白为什么这需要它自己的步骤,因为它应该被理解。如果是这样,我想确认一下。如果不是这样,我需要帮助理解。
  • 您的解释似乎是正确的。我可能遗漏了一些细节,但重要的部分是在我猜想的类型覆盖出现错误的情况下抛出异常。

标签: javascript ecmascript-harmony


【解决方案1】:

ReturnIfAbrupt 指的是突然完成。完成记录包含一个类型和与之关联的值。正常的完成类似于表达式的结果值。除了正常完成之外,函数的返回完成是通常的预期完成。任何其他完成类型都是突然的。那就是投掷,休息,继续。

if (isCompletionRecord(v)) {
  if (isAbruptCompletion(v)) {
    return v;
  } else {
    v = v.value;
  }
}

按照你的方式实现它,它需要将函数包装在 try catch 中。抛出的值将是突然完成。这不是你在 JS 级别看到的东西,它用于在引擎级别实现控制流和非本地控制传输。

我已经在 J​​S 虚拟机中实现了大部分 ES6 规范,这也可能有助于阐明它,这里是 ToInteger:https://github.com/Benvie/continuum/blob/master/lib/continuum.js#L516

function ToInteger(argument){
  if (argument && typeof argument === OBJECT && argument.IsCompletion) {
    if (argument.IsAbruptCompletion) {
      return argument;
    }
    argument = argument.value;
  }
  return ToNumber(argument) | 0;
}

【讨论】:

  • 谢谢!所以对我来说,它实际上意味着“什么都不做”。我觉得很奇怪。 ToNumber 甚至会导致突然完成吗?好像不是这样的。
  • 另外,如果我错了,请纠正我,但从我阅读我正在使用的草稿 (9-27-12) 来看,我认为这 ToInteger 可能不是 100% 准确的到ToNumber(argument) | 0 行。那不总是会导致有限的数字吗?草案似乎表明ToInteger 也可以产生无限值。
  • 这意味着什么都不做,除非你收到一个投掷。从“没有尝试捕获”的角度考虑它。实现 try..catch 的一种方法是完全按照规范执行。像正常结果一样返回“抛出”,但包装为“ThrownValue”类型并始终检查它。大多数时候你不需要做任何事情。但如果是特殊结果,则需要不加修改地传递它。对于 ToInteger 的事情,你确实是对的。我大概是一些运营商在期待第二次通过细节。
  • 另外值得注意的是 ReturnIfAbrupt 是一个不可观察的实现细节。该规范描述了可以观察到的情况,但实际的实现可能完全不同。一个例子是使用延续传递风格并拥有第二个“控制”通道,用于传递特殊结果,如 throws。在这种情况下,您永远不需要进行 ReturnIfAbrupt 检查,因为特殊值永远不会通过“正常”通道。
猜你喜欢
  • 2014-01-17
  • 2017-06-11
  • 2023-03-20
  • 2011-08-12
  • 2017-06-11
  • 2018-03-05
  • 2023-03-27
  • 2016-08-17
  • 2010-12-28
相关资源
最近更新 更多