在JavaScript中,函数声明和函数表达式是定义函数的两种不同方式,它们在语法和行为上有一些区别。
语法形式:
函数声明(Function Declaration)使用function
关键字后跟函数名、参数列表和函数体。例如:
function greet(name) {
console.log("Hello, " + name + "!");
}
函数表达式(Function Expression)将函数赋值给一个变量或属性,可以是匿名函数或具名函数。例如:
// 匿名函数表达式
var greet = function(name) {
console.log("Hello, " + name + "!");
};
// 具名函数表达式
var multiply = function multiply(a, b) {
return a * b;
};
变量提升(Hoisting):
函数声明会在执行代码之前被解析器提升到作用域的顶部。这意味着你可以在函数声明之前调用函数。例如:
greet("Alice"); // 正确,函数声明被提升
function greet(name) {
console.log("Hello, " + name + "!");
}
函数表达式不会被提升,因此必须在其定义之后才能调用。例如:
greet("Bob"); // 错误,函数表达式未被提升
var greet = function(name) {
console.log("Hello, " + name + "!");
};
函数名称:
函数声明可以使用函数名,该函数名在函数内部和外部都是可见的。例如:
function greet(name) {
console.log("Hello, " + name + "!");
}
console.log(greet.name); // 输出:greet
匿名函数表达式没有函数名,因此只能通过变量名来引用该函数。例如:
var greet = function(name) {
console.log("Hello, " + name + "!");
};
console.log(greet.name); // 输出:空字符串
作用域:
函数声明在其所属的作用域中创建一个局部函数。例如:
function foo() {
function bar() {
console.log("Inside bar");
}
bar(); // 调用局部函数
}
foo(); // 输出:Inside bar
bar(); // 报错,bar不在全局作用域中可见
函数表达式可以根据赋值位置决定函数的作用域。例如:
var foo = function() {
var bar = function() {
console.log("Inside bar");
};
bar(); // 调用局部函数
};
foo(); // 输出:Inside bar
bar(); // 报错,bar不在全局作用域中可见
总结来说,函数声明在变量提升时会被解析器提升到作用域顶部,可以在声明之前调用,而函数表达式不会被提升并且必须在定义之后才能调用。此外,函数声明有一个可选的函数名,在内部和外部都是可见的,而匿名函数表达式没有函数名只能通过变量名引用。另外,函数声明创建局部函数,作用域限于所属函数内部,而函数表达式的作用域可以根据赋值位置决定。