函数表达式与JavaScript中的声明之间有什么区别? [重复]

本文翻译自:What is the difference between a function expression vs declaration in JavaScript? [duplicate]

This question already has answers here : 这个问题已经在这里有了答案
Closed 6 years ago . 6年前关闭。

What is the difference between the following lines of code? 以下几行代码有什么区别?

//Function declaration
function foo() { return 5; }

//Anonymous function expression
var foo = function() { return 5; }

//Named function expression
var foo = function foo() { return 5; }
  • What is a named/anonymous function expression? 什么是命名/匿名函数表达式?
  • What is a declared function? 什么是声明函数?
  • How do browsers deal with these constructs differently? 浏览器如何不同地处理这些结构?

What do the responses to a similar question ( var functionName = function() {} vs function functionName() {} ) not get exactly right? 对类似问题( var functionName = function(){}与function functionName(){} )的回答有什么不正确的答案?


#1楼

参考:https://stackoom.com/question/4Fcv/函数表达式与JavaScript中的声明之间有什么区别-重复


#2楼

The first statement depends on the context in which it is declared. 第一条语句取决于声明它的上下文。

If it is declared in the global context it will create an implied global variable called "foo" which will be a variable which points to the function. 如果在全局上下文中声明,它将创建一个隐含的全局变量“ foo”,该变量将指向该函数。 Thus the function call "foo()" can be made anywhere in your javascript program. 因此,可以在您的javascript程序中的任何位置进行函数调用“ foo()”。

If the function is created in a closure it will create an implied local variable called "foo" which you can then use to invoke the function inside the closure with "foo()" 如果函数是在闭包中创建的,它将创建一个隐含的局部变量“ foo”,您可以使用该变量通过“ foo()”在闭包内调用该函数。

EDIT: 编辑:

I should have also said that function statements (The first one) are parsed before function expressions (The other 2). 我还应该说过,函数语句(第一个)在函数表达式(其他两个)之前进行解析。 This means that if you declare the function at the bottom of your script you will still be able to use it at the top. 这意味着,如果您在脚本的底部声明该函数,则仍然可以在顶部使用它。 Function expressions only get evaluated as they are hit by the executing code. 函数表达式只有在被执行代码击中时才会被求值。

END EDIT 结束编辑

Statements 2 & 3 are pretty much equivalent to each other. 陈述2和3彼此相当。 Again if used in the global context they will create global variables and if used within a closure will create local variables. 同样,如果在全局上下文中使用它们,则将创建全局变量,如果在闭包中使用,则将创建局部变量。 However it is worth noting that statement 3 will ignore the function name, so esentially you could call the function anything. 但是,值得注意的是,语句3将忽略函数名称,因此从本质上讲,您可以调用任何函数。 Therefore 因此

var foo = function foo() { return 5; }

Is the same as 是相同的

var foo = function fooYou() { return 5; }

#3楼

Though the complete difference is more complicated, the only difference that concerns me is when the machine creates the function object. 尽管完全的区别更加复杂,但是与我有关的唯一区别是机器创建功能对象时。 Which in the case of declarations is before any statement is executed but after a statement body is invoked (be that the global code body or a sub-function's), and in the case of expressions is when the statement it is in gets executed. 在声明的情况下,这是在执行任何语句之前但在调用语句主体之后(是全局代码主体或子函数的那个​​),在表达式的情况下,是执行该语句所处的时间。 Other than that for all intents and purposes browsers treat them the same. 出于所有意图和目的,浏览器均将其视为相同。

To help you understand, take a look at this performance test which busted an assumption I had made of internally declared functions not needing to be re-created by the machine when the outer function is invoked. 为了帮助您理解,请看一下此性能测试 ,该测试否定了我对内部声明的函数所做的假设,在调用外部函数时无需由机器重新创建内部声明的函数。 Kind of a shame too as I liked writing code that way. 我也喜欢那样写代码,这也有点可耻。


#4楼

Function Declaration 功能声明

function foo() { ... }

Because of function hoisting , the function declared this way can be called both after and before the definition. 由于函数提升 ,可以在定义之后和定义之前调用以这种方式声明的函数。

Function Expression 函数表达式

  1. Named Function Expression 命名函数表达式

     var foo = function bar() { ... } 
  2. Anonymous Function Expression 匿名函数表达式

     var foo = function() { ... } 

foo() can be called only after creation. 只有创建后才能调用foo()

Immediately-Invoked Function Expression (IIFE) 立即调用函数表达式(IIFE)

(function() { ... }());

Conclusion 结论

Crockford recommends to use function expression because it makes it clear that foo is a variable containing a function value. Crockford建议使用函数表达式,因为它可以清楚地表明foo是包含函数值的变量。 Well, personally, I prefer to use Declaration unless there is a reason for Expression. 好吧,就我个人而言,除非有理由表达,否则我更喜欢使用声明。


#5楼

Regarding 3rd definition: 关于第三个定义:

var foo = function foo() { return 5; }

Heres an example which shows how to use possibility of recursive call: 这是一个示例,显示了如何使用递归调用的可能性:

a = function b(i) { 
  if (i>10) {
    return i;
  }
  else {
    return b(++i);
  }
}

console.log(a(5));  // outputs 11
console.log(a(10)); // outputs 11
console.log(a(11)); // outputs 11
console.log(a(15)); // outputs 15

Edit: more interesting example with closures: 编辑:与闭包更有趣的示例:

a = function(c) {
 return function b(i){
  if (i>c) {
   return i;
  }
  return b(++i);
 }
}
d = a(5);
console.log(d(3)); // outputs 6
console.log(d(8)); // outputs 8

#6楼

They're actually really similar. 它们实际上真的很相似。 How you call them is exactly the same.The difference lies in how the browser loads them into the execution context. 调用它们的方式完全相同。不同之处在于浏览器如何将它们加载到执行上下文中。

Function declarations load before any code is executed. 函数声明在执行任何代码之前先加载。

Function expressions load only when the interpreter reaches that line of code. 仅在解释器到达该行代码时才加载函数表达式。

So if you try to call a function expression before it's loaded, you'll get an error! 因此,如果您尝试在函数表达式加载之前调用它,则会收到错误消息! If you call a function declaration instead, it'll always work, because no code can be called until all declarations are loaded. 如果您改为调用函数声明,它将始终有效,因为在加载所有声明之前,无法调用任何代码。

Example: Function Expression 示例:函数表达式

alert(foo()); // ERROR! foo wasn't loaded yet
var foo = function() { return 5; } 

Example: Function Declaration 示例:函数声明

alert(foo()); // Alerts 5. Declarations are loaded before any code can run.
function foo() { return 5; } 


As for the second part of your question: 至于问题的第二部分:

var foo = function foo() { return 5; } var foo = function foo() { return 5; } is really the same as the other two. var foo = function foo() { return 5; }实际上与其他两个相同。 It's just that this line of code used to cause an error in safari, though it no longer does. 只是这行代码曾经导致safari中的错误,尽管不再发生。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值