问题
I'm currently implementing some shims for the ES6 draft. I'm wondering if anyone can tell me what ReturnIfAbrupt
means. For instance, my implementation for Number.toInt
(which calls internal [[ToInteger]]
is as follows:
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
});
Step 2 is ReturnIfAbrupt(number)
. You'll notice I currently have // ?
for that step because I'm not sure what to do. What does it mean when it says ReturnIfAbrupt(...)
?
I have read the section on ReturnIfAbrupt
in the draft, however I am unable to understand what to do for step 2, what to put in place of // ?
in the code above.
From my reading, it may be that nothing should be done, and the ReturnIfAbrupt
step merely means to let any error which occurred in ToNumber to propagate up, exiting the function. However, that seems overly verbose, as I would think it could go without saying. Also, it doesn't seem to me like ToNumber
can even throw an error. Could someone confirm or help me to understand the real meaning?
回答1:
ReturnIfAbrupt is referring to an Abrupt Completion. A completion record contains a type and the value associated with it. A normal completion would be something like an expression's resulting value. A return completion from a function is the usual expected completion aside from a normal completion. Any other completion types are abrupt. That's throw, break, continue.
if (isCompletionRecord(v)) {
if (isAbruptCompletion(v)) {
return v;
} else {
v = v.value;
}
}
Implementing it as you are, what it would entail is wrapping the function in a try catch. A thrown value would be an abrupt completion. This isn't something you see at the JS level though, it's for implementing control flow and non-local control transfers at the engine level.
I've implemented much of the ES6 spec in a JS virtual machine that may also help shed some light on it, here's 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;
}
来源:https://stackoverflow.com/questions/12995554/what-does-returnifabrupt-mean-in-es6-draft