首页 > var f = function g(){ return 23; }; typeof g(); 报错,而不是“number”

var f = function g(){ return 23; }; typeof g(); 报错,而不是“number”

var f = function g(){ return 23; };  typeof g();

为什么是报错,而不是“number”,


强行回答一个~ 补充一下@manxisuo 的答案。

(以下截图均来自ES5标准文档,内容是本人阅读后的理解)

首先,我们知道函数的定义有两种方式:

函数声明在程序 (Program) 中有着非比寻常的优先级:

一段ES程序就是由语句 (Statement) 和函数声明组成的。

显然 var f = function g(){ return 23; }; 是一段语句,而非函数声明。具体来说,是一段变量语句 (VariableStatement) 。等号右侧被解释为赋值语句 (AssignmentExpression) ,再经过一系列的解释后,被确定为函数表达式。等号左侧变量将被赋值为右侧函数表达式解释执行后的引用。

因此问题的关键在于函数表达式是如何解释执行的。

再看函数表达式的语法,函数名是一个可选项。而函数名的有无,函数表达式的解释执行步骤有着巨大的差异。

function ( FormalParameterListopt ) { FunctionBody }

当没有函数名时,函数表达式的解释执行与函数声明相似,作用域即为当前执行的词法环境。后者,函数声明会执行一个抽象方法CreateMutableBinding,在环境记录项中创建一个新的可变绑定(即变量)。从这里可以知道,新创建的变量就在当前的作用域内。

function Identifier ( FormalParameterListopt ) { FunctionBody }

重点来了,指定了函数名的函数表达式,会首先执行一个抽象方法NewDeclarativeEnvironment,该方法创建一个空的新词法环境,并把 当前的执行环境 引用为 新的词法环境的外部词法环境。然后以新的词法环境为作用域,执行了接下来的步骤,并最后将函数的引用交给左侧的变量。因此这里的函数名,是绑定在新的词法环境中的,外部环境也就无法找到函数名,抛出了ReferenceError。

另外@manxisuo 所说,也同样可以解释了。

以上。

Reference


这种形式叫做命名的函数表达式,它的名字g只在函数体内可见。在函数外部不可见,所以报错。

你在函数体内console.log(g)试一下。

详情参考ECMAScript。


这种问题也跑来问?看下错误具体信息就知道是函数 g 没定义,为什么没定义呢?肯定是定义的部分出错了嘛,动动脑子啊,哥们儿。


typeof 引用


var f = function g(){ return 23; };
运行后,g就没有了。
上述代码等同于

var f = function(){ return 23; };

而如果是

function g(){ return 23; }; 

那么g还是存在的。

【热门文章】
【热门文章】