当函数作为参数传递时,Javascript函数提升不适用?

问题描述:

Javascript有这个有趣的东西叫函数提升,这意味着我们可以使用函数表达式之前(即,视觉上)它被宣布为(谨慎:我的措辞可能不正确,随时对其发表评论)当函数作为参数传递时,Javascript函数提升不适用?

fn1(); // works OK 
function fn1() {console.log('fn1');} 

但是,如果我们传递一个命名函数作为参数,函数提升不会发生。语法看起来很相似,但我想这不是一个函数表达式,而是一个命名的匿名函数(!)。

fn2(); // throws a ReferenceError as fn2 is not defined 
setTimeout(function fn2() {console.log('fn2')}, 0); 
  • 是它确实是一个函数表达式和一个名为拉姆达之间的差异?
  • 两者之间还有其他显着差异吗?
  • 考虑到fn2是一个命名的lambda,是否可以从fn2本身之外的任何地方访问其名称?
+0

@Sean我不认为这是相同的问题:我不使用'var'在任何情况下,我的功能都在两种情况下命名。我使用与该问题不同的完全相同的语法。 – Greg 2014-11-05 02:23:08

+1

就是这样,你*不使用完全相同的语法。第一种情况是“函数声明”(如果你愿意的话,语法A),而第二种情况是“命名函数表达式”(语法B)。这两种用于声明函数的不同语法具有不同的行为,如建议的重复问题和我在第一条评论中链接到的文章中所讨论的。 – 2014-11-05 02:28:24

+1

by所指的“命名函数表达式”只是一个正常函数表达式。 * only *指定了一个“named”和一个“匿名”函数表达式(我知道)之间的区别是指定表达式的名称在函数的作用域中可用。 – 2014-11-05 02:31:21

唯一功能语句/声明应绑定相应的变量(并有可能提升)。

参数列表中的setTimeout函数被视为函数表达式;它有一个名称(“fn2的”),但是不绑定到变量fn2和是之前创建的表达被评估 ..

+0

'理想',你的意思是它绑定到一些JS引擎上的变量fn2? – Greg 2014-11-05 02:25:21

+0

@Greg我已经编辑出来了。很久以前,在IE中,看起来像函数声明的函数表达式(例如,在'if'中)将被视为函数声明。在反思中,我不相信这会影响表达式中的函数表达式。 – user2864740 2014-11-05 02:27:46

+1

函数声明在大多数浏览器中不被支持,并且在那些函数声明中不被“悬挂”。他们也不允许在严格模式下使用。 – RobG 2014-11-05 02:50:09

考虑fn2的是一个命名的λ,是可访问的fn2的名称从fn2本身以外的任何地方?

在越野车版本的IE中,是的。命名函数表达式在封闭执行上下文中被创建为变量(与ECMA-262不一致)。见Named function expressions demystified