Heim > Fragen und Antworten > Hauptteil
var f = function g(){ return 23; }; typeof g();
为什么是报错,而不是“number”,
PHPz2017-04-10 17:30:44
这种形式叫做命名的函数表达式,它的名字g只在函数体内可见。在函数外部不可见,所以报错。
你在函数体内console.log(g)
试一下。
详情参考ECMAScript。
黄舟2017-04-10 17:30:44
var f = function g(){ return 23; };
运行后,g就没有了。
上述代码等同于
var f = function(){ return 23; };
而如果是
function g(){ return 23; };
那么g还是存在的。
伊谢尔伦2017-04-10 17:30:44
强行回答一个~ 补充一下@manxisuo 的答案。
(以下截图均来自ES5标准文档,内容是本人阅读后的理解)
首先,我们知道函数的定义有两种方式:
函数声明 (FunctionDeclaration)
函数表达式 (FunctionExpression)
函数声明在程序 (Program) 中有着非比寻常的优先级:
一段ES程序就是由语句 (Statement) 和函数声明组成的。
显然 var f = function g(){ return 23; }; 是一段语句,而非函数声明。具体来说,是一段变量语句 (VariableStatement) 。等号右侧被解释为赋值语句 (AssignmentExpression) ,再经过一系列的解释后,被确定为函数表达式。等号左侧变量将被赋值为右侧函数表达式解释执行后的引用。
因此问题的关键在于函数表达式是如何解释执行的。
再看函数表达式的语法,函数名是一个可选项。而函数名的有无,函数表达式的解释执行步骤有着巨大的差异。
当没有函数名时,函数表达式的解释执行与函数声明相似,作用域即为当前执行的词法环境。后者,函数声明会执行一个抽象方法CreateMutableBinding,在环境记录项中创建一个新的可变绑定(即变量)。从这里可以知道,新创建的变量就在当前的作用域内。
重点来了,指定了函数名的函数表达式,会首先执行一个抽象方法NewDeclarativeEnvironment,该方法创建一个空的新词法环境,并把 当前的执行环境 引用为 新的词法环境的外部词法环境。然后以新的词法环境为作用域,执行了接下来的步骤,并最后将函数的引用交给左侧的变量。因此这里的函数名,是绑定在新的词法环境中的,外部环境也就无法找到函数名,抛出了ReferenceError。
另外@manxisuo 所说,也同样可以解释了。
以上。
ECMA-262标准文档
ES5/函数定义 - HTML5 Chinese Interest Group Wiki