var functionName = function() {} 与 function functionName() {} 有什么区别?

7613

最近我开始维护别人的JavaScript代码。我正在修复错误,添加功能,并尝试整理代码并使其更加一致。

之前的开发人员使用了两种声明函数的方式,我无法确定是否有什么原因。

这两种方式是:

var functionOne = function() {
    // Some code
};

而且,

function functionTwo() {
    // Some code
}

为什么要使用这两种不同的方法,各自有哪些优缺点?是否有一种方法可以做到另一种方法无法实现的事情?

41个回答

7

new Function()可以用于将函数体传递为字符串。因此,它可以用于创建动态函数。同时也可以在不执行脚本的情况下传递脚本。

var func = new Function("x", "y", "return x*y;");
function secondFunction(){
   var result;
   result = func(10,20);
   console.log ( result );
}

secondFunction()

这并没有回答这里提出的问题。 - undefined

6

这被称为函数表达式:

var getRectArea = function(width, height) {
    return width * height;
};

console.log("Area of Rectangle: " + getRectArea(3,4));
// This should return the following result in the console: 
// Area of Rectangle: 12

这被称为函数声明:

var w = 5;
var h = 6;

function RectArea(width, height) {  //declaring the function
  return area = width * height;
}                                   //note you do not need ; after }

RectArea(w,h);                      //calling or executing the function
console.log("Area of Rectangle: " + area);
// This should return the following result in the console: 
// Area of Rectangle: 30

希望这有助于解释函数表达式和函数声明之间的区别以及如何使用它们。谢谢。

3

我更喜欢将函数定义为变量:

let first = function(x){
   return x[0];
}

改为:

function first(){
    ....
}

因为我可以在定义函数时使用表达式和装饰器,例如:

let safe = function(f){
  try {f()...}
}
let last = safe(function(x){return x[0]}).

使用ES6,代码更加简短:

 let last = x => x[0]
 ...........
 function last(x){
     return x[0];
 }
......

let last = safe(x => x[0]);

3

函数声明和函数表达式的区别:

Javascript 拥有一流函数。这意味着它们可以像任何其他变量一样处理。函数可以作为参数传递到函数中,从函数返回,并且可以存储在变量中。

然而,将函数存储在变量中(函数表达式)并不是创建函数的唯一方法,还可以通过函数声明来完成。以下是两者的关键区别:

  1. 函数表达式可以是匿名的,而函数声明必须有一个名称。
  2. 两者都有一个名称属性,用于标识函数。函数表达式的名称属性是它绑定的变量的名称,而函数声明的名称只是给定的名称。
  3. 函数声明被提升,而函数表达式不会被提升。只有变量被提升以具有 "undefined" 的值。

以下是一个示例:

try {
  functionOne();
} catch (e) {
  console.log('i cant run because im not hoisted');
}

functionTwo();

// function expression, does not get hoisted
let functionOne = function randomName() {
    // Some code
};

// function declaration, gets hoisted
function functionTwo() {
   console.log('I get hoisted');
}

try {
  randomName(); // this isn't the proper name, it is functionOne
} catch (e) {
  console.log('You cant call me with randomName my name is function one');
}

:


let functionOne 的声明被提升了。但它没有被初始化,甚至没有被赋值为 undefined。因此,会出现错误:_Uncaught ReferenceError: Cannot access 'functionOne' before initialization_。 - Pavlo Maistrenko

2

需要注意的一个重要点是:

假设有两个函数:

sum(1,2);

const sum = function(first, second) {
  return first + second;
}

在上述情况下,会出现错误提示sum未定义,但是。
sum(1,2);

function sum(first, second) {
  return first + second;
}

在这种情况下,由于存在变量提升,因此此函数不会出现任何错误。


1

JavaScript表达式: 返回一个值的内容
示例: 在Chrome控制台中尝试以下操作:

a = 10
output : 10

(1 + 3)
output = 4

声明/语句:不返回值的语句
示例:

if (1 > 2) {
 // do something. 
}

这里 (1>2) 是一个表达式,但 'if' 语句不是。它没有返回任何内容。


同样地,我们有函数声明/语句和函数表达式
让我们举个例子:

// test.js

var a = 10;

// function expression
var fun_expression = function() {
   console.log("Running function Expression");
}

// funciton expression

function fun_declaration() {
   console.log("Running function Statement");
}

重要提示:当JavaScript引擎运行上述js文件时会发生什么。

  • 当此js运行时,以下事情将发生:

    1. 将创建变量'a'和'fun_expression'的内存,并为函数语句'fun_declaration'创建内存。
    2. 'a'将被赋值为'undefined'。'fun_expression'将被赋值为'undefined'。'fun_declaration'将完整地存在于内存中。
      注意:以上步骤1和2称为“执行上下文 - 创建阶段”。

现在假设我们更新js如下。

// test.js

console.log(a)  //output: udefined (No error)
console.log(fun_expression)  // output: undefined (No error)
console.log(fun_expression()) // output: Error. As we trying to invoke undefined. 
console.log(fun_declaration()) // output: running function statement  (As fun_declaration is already hoisted in the memory). 

var a = 10;

// function expression
var fun_expression = function() {
   console.log('Running function expression')
}

// function declaration

function fun_declaration() {
   console.log('running function declaration')
}

console.log(a)   // output: 10
console.log(fun_expression()) //output: Running function expression
console.log(fun_declaration()) //output: running function declaration

上面评论中提到的输出结果,应该有助于理解函数表达式和函数语句/声明之间的区别。


1
在调试器/开发者工具的断点中,如果您在控制台中使用格式function functionName() {},则随后无法在控制台中使用functionName()(它会显示“未定义”),而在var functionName = function() {}之后,则可以使用该函数。
请参见此问题

1

对于函数声明,您无法使用.bind()方法,但是对于函数表达式可以使用。

函数声明:

function x() {
  console.log(this)
}.bind('string')

x()

函数表达式:

var x = function() {
  console.log(this)
}.bind('string')

x()


0

var functionOne = function() {}定义在运行时,function functionTwo() {}在解析时定义。

// Run-Time function declaration 
functionOne(); // Calling functionOne function here will give an Error
var functionOne = function () {
  // Some code
};

// Parse-Time function declaration 
functionTwo(); // Calling functionTwo function will not give an Error
function functionTwo() {
  // Some code...
}

运行时与解析时的解释 JavaScript 运行时 vs 解析时


0

try {
  console.log("Success: ", add(1, 1));
} catch(e) {
  console.log("ERROR: " + e);
}

var add=function(a, b){
  return a + b;
}


2
这不是一个答案,而是一个代码示例。它需要解释它展示了什么,并且还需要提供另一种类型的声明函数的反例。 - Richard Garside

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接