ECMAScript 5.1 [[Call]]内部方法第2、4-6条款技术问询
Hey there, let's unpack your questions about ECMAScript 5.1's [[Call]] internal method—this spec language can be pretty opaque, so I'll translate it into practical terms with examples where I can.
Questions about Clause 2 of [[Call]]
Clause 2 covers evaluating the function's code (or falling back if there's no code to evaluate). Here's your breakdown:
1. What does the evaluation result of FunctionBody refer to, and how is it calculated?
The FunctionBody is just the actual code inside your function's curly braces { ... }. When you call the function, the JS engine executes every line of that code following ES5.1's execution rules. The "evaluation result" is a completion record—the engine's way of tracking how execution wrapped up.
For example:
- If your function ends with
return 42;, the evaluation result is a completion record marked asreturnwith a value of42. - If there's no return statement (e.g.,
function greet() { console.log("hello"); }), the result is anormalcompletion with a value ofundefined. - If the code hits an uncaught
throw new Error("oops"), the result is athrowcompletion with the Error object as its value.
2. What scenarios would a function F not have a [[Code]] property?
In ES5.1, most functions you write (function declarations, function expressions) have a [[Code]] internal property that stores their FunctionBody. The only common exception is built-in native functions—things like Object.prototype.toString, Array.prototype.push, or Math.sqrt. These aren't written in JavaScript; they're implemented directly in the engine's native code (like C++ for V8). Since there's no JS FunctionBody to store, these functions don't have a [[Code]] property. When you call them, the engine skips the FunctionBody evaluation step and runs the native implementation directly.
3. What does the record (normal, undefined, empty) mean?
This is a specific completion record, which has three parts:
normal: Execution finished without any interruptions—noreturn, nothrow, and no jump statements (likebreak/continue) that exit the function.undefined: The value associated with this completion. Since there's no explicit return, the function implicitly returnsundefined.empty: This refers to the target label for jump statements. Since this is a normal completion with no jump, this field is empty.
Questions about Clauses 4, 5, 6 of [[Call]]
These clauses handle the completion record from the function's execution and determine what the function call ultimately returns (or whether it throws an error). Let's break down result.type and result.value:
What is result.type, and where does it come from?
result.type tells the engine how the function's execution ended. It can be one of three key values in this context:
normal: Execution reached the end of the FunctionBody without any explicitreturnor uncaughtthrow.return: Execution stopped because areturnstatement was encountered.throw: Execution stopped because an uncaught exception was thrown.
The engine sets this type as it executes the function's code. For example:
function log() { console.log("done"); }→result.typeisnormal.function giveFive() { return 5; }→result.typeisreturn.function fail() { throw new Error("broken"); }→result.typeisthrow.
What is result.value, and where does it come from?
result.value is the data associated with the completion record:
- If
result.typeisreturn, the value is whatever was passed toreturn(e.g.,return "hello"gives"hello",return;givesundefined). - If
result.typeisnormal, the value is alwaysundefined(the implicit return value of functions with noreturn). - If
result.typeisthrow, the value is the exception object that was thrown (like the Error instance in thefail()example above).
Now let's tie this directly to clauses 4-6:
- Clause 4: If
result.typeisthrow, we propagate that exception—meaning the error bubbles up to the caller (unless caught by atry/catchblock). - Clause 5: If
result.typeisreturn, we returnresult.valueas the function's final return value. - Clause 6: If
result.typeisnormal, we returnundefined(matching theresult.valuefor normal completions).
内容的提问来源于stack exchange,提问作者MaximPro

