函数声明与函数表达式

来源:互联网 发布:客服数据分析表 编辑:程序博客网 时间:2024/03/29 17:23

定义形式

函数作为JavaScript中的一等公民,使用可谓相当广泛。定义函数的方法主要有两种,即函数声明函数表达式

函数声明必须以function关键字开始,且必须有标识符(即函数名称),它的定义形式为:

function 函数名(参数:可选){    //函数体}

函数表达式的函数名则是可选的,它的定义形式为:

function 函数名(可选)(参数:可选){    //函数体}

可以看出,如果不声明函数名称,则必为函数表达式。声明函数名称时,如果function foo(){}是作为赋值表达式的一部分时,也为函数表达式。如果function foo(){}被包含在一个函数内部或是位于全局作用域中的话,它就是一个函数声明。

区别

1.函数声明必须有函数名,函数表达式的函数名则是可选的。

var add = function (a ,b){    console.log(a + b);}add(2, 3);

如上面代码所示,是一个函数表达式。它定义了一个匿名函数,并将这个函数赋值给变量add。注意这里add并不是函数的函数名。

2.二者出现的位置不同。函数声明只能在代码的最外部或者是函数体内;函数表达式可以出现在表达式可以出现的任何地方。

3.函数声明语句会被提前到外部脚本或外部作用域顶部,所以以这种方式声明的函数,可以被在它定义之前出现的代码所使用;以函数表达式方式定义的函数在定义之前则无法调用。

如下面代码所示:

sub(3, 1);//"2"add(1, 2);//"Uncaught TypeError: add is not a function"function sub(a, b){    console.log(a - b);}var add = function (a ,b){    console.log(a + b);};

讲到提升,这里要多说两句。

JavaScript通常被认为是一种“解释执行语言”,但事实上它是一门编译语言。它的运行也要经过编译执行两个步骤。简单来说,引擎会在解释JavaScript代码之前首先对其进行编译。编译阶段中的一部分工作就是找到所有的声明,并用合适的作用域将它们关联起来。因此,包括变量和函数在内的所有声明都会在任何代码被执行之前被处理。

举个例子,var a = 2;当你看到这句代码时,你可能认为它是一个声明。但实际上JavaScript会将它看成两个声明:“var a;“和“a = 2;“。第一个定义声明是在编译阶段进行的,第二个赋值声明会被留在原地等待执行阶段。

回到上面的例子,函数声明sub被提升了,所以sub(3, 1)可以正常执行。而函数表达式add相当于以下代码:

var add;add(1, 2);add = function (a ,b){    console.log(a + b);};

代码执行到add(1, 2)这一句时,变量add已经被定义了,但赋值操作并没有被执行,add此时为undefined,把它当做一个函数来调用,当然会报错了。

那么,问题又来了:既然变量和函数声明都会被提升,那么到底它们哪个优先级高呢?

这里有几个细节需要注意:

1.函数声明会被首先提升,然后才是变量。也就是说,函数声明会被提升到普通变量之前。

2.出现在后面的函数声明会覆盖前面的。

0 0