JavaScript - 为什么在函数表达式中创建的函数声明会是“未定义”的?

3

我正在试图理解这个函数表达式。

如果我创建一个包含函数声明的函数表达式 (p),那么函数声明 a() 返回 undefined。

var p;
p = function a() { return 'Hello' }

typeof p; // returns 'function'
typeof a; // returns 'undefined'

有人可以解释一下为什么会这样吗?

如果我的术语使用不正确,请告诉我。


你想这样做的原因是什么?如果需要两者,可以使用function a() { return "Hello" } var p = a;,或者不指定匿名函数的名称。 - Ian
@Ian: "或者不要给匿名函数指定名称..." 嗯... ;-) - T.J. Crowder
@T.J.Crowder 除了函数能够访问自身之外,我不认为给匿名函数命名有什么用处...这显然也让 OP 感到困惑! - Ian
1
@Ian:我只是在指出,如果它有一个名字,它就不是匿名的,因此说“...不要给匿名函数起名字...”是自相矛盾的。 :-) - T.J. Crowder
1
@T.J.Crowder 哈哈,是的,我明白了。我的措辞有点不好。我只是太习惯于从不给函数表达式命名了。 - Ian
3个回答

5

这不是一个函数声明,而是一个带有名称的函数表达式。该名称不会创建变量,但您可以在对象上看到它。

quentin@raston ~ $ node
> var p;
undefined
> p = function a() { return 'Hello' }
[Function: a]
> typeof p; // returns 'function'
'function'
> typeof a; // returns 'undefined'
'undefined'
> p
[Function: a]
> p.name
'a'
>

2
值得注意的是:函数名也将作为标识符在函数体内可用,因此可以递归调用命名函数表达式。 - bfavaretto
2
值得注意的是,函数实例的 name 属性是非标准的。 - T.J. Crowder

1

如果我创建一个看起来包含函数声明的函数表达式(p)

不是的。这是一个命名函数表达式,其中不包含函数声明。函数表达式的名称在函数作用域内作为标识符可用(指向函数本身),并且作为非标准的name属性


真不敢相信没有人提到 kangax 的网站链接。 - Bergi

-3

6
"您创建了一个匿名函数声明。"不,他/她没有。首先,它不是匿名的。其次,它不是一个声明。它是一个"具有名称的函数表达式"。(函数声明和函数表达式是不同的东西;JavaScript有两者。如果它被用作右侧值,那么您知道它是一个表达式。) 您是完全正确的,a在函数内部是在范围内的,但在外部则不是。(顺便说一句,这不是我的负评。) - T.J. Crowder
抱歉,我的术语可能有误 - 我的目标是表达问题的要点。您会如何描述它? - samjudson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接