JavaScript:函数表达式与声明差异及if语句中标识符作用域疑问
Great question — this dives into some easy-to-miss JavaScript rules around function parsing and variable scoping, especially when code is placed in unexpected spots like condition checks. Let’s break this down step by step.
第一个案例:if ( function f() { } ) { console.log( typeof f ); } → 返回undefined
First, let’s clarify what’s happening here. When you write function f() {} directly inside the parentheses of an if condition, you’re not writing a function declaration — you’re creating a named function expression (NFE).
The critical rule for named function expressions is this: the function’s name (in this case, f) is only accessible inside the function’s own body. It does not get hoisted to the surrounding scope (whether that’s the global scope or the block scope of the if statement).
Here’s the play-by-play when this code runs:
- The
function f() {}is evaluated as an expression. Since functions are truthy values in JavaScript, theifcondition passes, and the block executes. - Inside the
ifblock, when we checktypeof f, the JavaScript engine looks for a variable namedfin the current scope and up the scope chain. Because the NFE’s namefis confined strictly to the function’s internal scope, there’s no accessiblefvariable here — hence the resultundefined.
As a quick test to confirm this, if we called the function from inside its own body, f would work perfectly:
if ( function f() { console.log(f); } ) { // 直接在表达式里调用函数,会打印函数本身 (function f() { console.log(f); })(); }
The name f only exists inside that function’s scope — outside of it, it’s invisible.
第二个案例:if ( f = 'assigned' ) { console.log( typeof f ); } → 返回string
This scenario is straightforward once you understand assignment expressions and implicit global variables:
- The
f = 'assigned'is an assignment operation that sets the value'assigned'to the variablef. - In non-strict mode (the default in most environments), if
fhasn’t been declared withvar,let, orconstbeforehand, JavaScript automatically creates a global variable namedf. - By the time the
ifblock runs,fexists in the global scope and holds the string value, sotypeof fcorrectly returnsstring.
Note: In strict mode ('use strict';), this would throw a ReferenceError instead, since implicit global variables are not allowed.
核心差异总结
The key distinction here boils down to how JavaScript treats declarations vs. expressions:
- Function declarations are hoisted to their enclosing scope (global or function-level) and create a variable in that scope using the function’s name.
- Function expressions (even named ones) do not create a variable in the surrounding scope. The name of a named function expression is purely a local variable inside the function itself.
When you place a function inside an if condition, it’s treated as an expression, not a declaration — so its name never leaks to the surrounding block or scope.
内容的提问来源于stack exchange,提问作者manjeet

