Javascript函数声明和函数表达式

deltamaster posted @ Mar 21, 2014 09:00:02 PM in JavaScript , 1671 阅读

先看一下下面的代码:

var a = function(x) {document.write(x + "\n");}(1); // OK - output "1"
function(x) {document.write(x + "\n");}(1); // Uncaught SyntaxError: Unexpected token (

小伙伴们就议论开了,为什么第一行的程序运行成功,而第二行的程序有语法错误呢?错误信息里提到的“(”是指哪一个括号呢?

之后又诞生了一系列的写法,来分别验证结果:

function f(x){document.write(x + "\n");}(1); // No output
(function(x) {document.write(x + "\n");})(1); // OK - output "1"
(function(x) {document.write(x + "\n");}(1)); // OK - output "1"
+function(x) {document.write(x + "\n");}(1); // OK - output "1"
~function(x) {document.write(x + "\n");}(1); // OK - output "1"

在这里先直接揭晓答案,在语句开头出现function,则被视为函数声明(FunctionDeclaration),否则视为函数表达式(FunctionExpression)。两者都同样构造一个函数对象,但是有两个区别:

  1. 函数声明必须有函数名作为函数标识符,而对于函数表达式则是可选的。(上面报出语法错误的那行代码,实际上是说不允许函数声明不含有标识符)
  2. 函数声明是与语句(Statement)平级,不求值的语法元素,而表达式有返回值。(上面没有输出的那行代码,是因为被视为一句函数声明,还有一句是(1);语句)

为何这样设计?

当解释器进行语法分析时,期待读入一个Statement或FunctionDeclaration,此时读入到词法元素“function”。此时就有了二义性,这里既可能是FunctionDeclaration的第一个词法元素,也可能是ExpressionStatement的第一个语法元素(即其中FunctionExpression的第一个词法元素),为了避免这种二义性,规定在这种情况下,将这个“function”视作FunctionDeclaration的第一个词法元素,于是就有了上面的结论和实验结果。

* 本文在CC BY-SA(署名-相同方式共享)协议下发布。
  • 无匹配
  • 无匹配

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter