定义函数有两种方法:一种是函数声明,另一种是函数表达式。
1. 函数声明
function functionName(arg0, arg1, arg2) {
//函数体
}
FireFox、Safari、Chrome 和 Opera 都给函数定义了一个非标准的 name
属性,通过这个属性可以访问到给函数指定的名字,也就是 function
关键字后面的标识符。
//只在 FireFox、Safari、Chrome 和 Opera 有效
alert(functionName.name);
关于函数声明,一个重要的特征就是函数声明提升,意思是在执行代码之前会先读取函数声明,这意味着可以把函数声明放在调用它的语句后面。
sayHi(); //正确,因为函数声明提升
function sayHi() {
alert("Hi!");
}
2. 函数表达式
var functionName = function(arg0, arg1, arg2) {
//函数体
}
这种语句就像是变量赋值语句,即创建一个函数并将它赋值给变量。这种函数叫做匿名函数,因为 function
关键字后面没有标识符,匿名函数的 name
属性是空字符串。
函数表达式与其他表达式一样,在使用前必须先赋值。
sayHi(); //抛出错误,因为函数还不存在
var sayHi = function() {
alert("Hi!");
}
使用函数表达式,相当于函数名是左边表达式,而不再会是右边的表达式中的名称。如果右边使用具名函数,那么不管是前面后面使用这个具名函数,都会报错。
let a = function b() {
}
b; //=> undefined
a; //=> function
3. 区别
理解函数提升的关键,就是理解函数声明和函数表达式之间的区别。
//错误,不能这样做
if(condition) {
function sayHi() {
alert("Hi!");
}
}
else {
function sayHi() {
alert("YO!");
}
}
//正确,可以使用函数表达式
var sayHi;
if(condition) {
sayHi = function() {
alert("Hi!");
}
}
else {
sayHi = function() {
alert("YO!");
}
}
能够创建函数再赋值给变量,也就能够把函数作为其他函数的值返回
function createComparisonFunction(propertyName) {
return function(object1, object2) {
var value1 = object1[propertyName];
var value2 = object2[propertyName];
if (value1 < value2) {
return -1;
}
else if (value1 > value2) {
return 1;
}
else {
return 0;
}
}
}
这样就返回了一个匿名函数,返回的函数可能被赋值给一个变量,或者以其他方式被调用