为什么要使用命名函数表达式? [英] Why use named function expressions?

查看:25
本文介绍了为什么要使用命名函数表达式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有两种不同的方式在 JavaScript 中进行函数表达式:

We have two different way for doing function expression in JavaScript:

命名函数表达式 (NFE):

var boo = function boo () {
  alert(1);
};

匿名函数表达式:

var boo = function () {
  alert(1);
};

并且它们都可以用 boo(); 调用.我真的不明白为什么/何时应该使用匿名函数以及何时应该使用命名函数表达式.它们之间有什么区别?

And both of them can be called with boo();. I really can't see why/when I should use anonymous functions and when I should use Named Function Expressions. What difference is there between them?

推荐答案

在匿名函数表达式的情况下,函数是匿名 —从字面上看,它没有名字.您分配给它的变量有一个名称,但函数没有.(更新:ES5 确实如此.从 ES2015 [又名 ES6] 开始,通常使用匿名表达式创建的函数会获得真实名称 [但不是自动标识符],请继续阅读...)

In the case of the anonymous function expression, the function is anonymous — literally, it has no name. The variable you're assigning it to has a name, but the function does not. (Update: That was true through ES5. As of ES2015 [aka ES6], often a function created with an anonymous expression gets a true name [but not an automatic identifier], read on...)

名称很有用.名称可以在堆栈跟踪、调用堆栈、断点列表等中看到.名称是好东西™.

Names are useful. Names can be seen in stack traces, call stacks, lists of breakpoints, etc. Names are a Good Thing™.

(您曾经不得不提防旧版本 IE [IE8 及以下] 中的命名函数表达式,因为它们错误地在两个完全不同的时间创建了两个完全独立的函数对象 [更多见我的博客文章 双拍].如果你需要支持IE8 [!!],最好坚持使用匿名函数表达式或函数声明,但避免命名函数表达式.)

(You used to have to beware of named function expressions in older versions of IE [IE8 and below], because they mistakenly created two completely separate function objects at two completely different times [more in my blog article Double take]. If you need to support IE8 [!!], it's probably best to stick with anonymous function expressions or function declarations, but avoid named function expressions.)

命名函数表达式的一个关键是它为函数体内的函数创建了一个具有该名称的作用域内标识符:

One key thing about a named function expression is that it creates an in-scope identifier with that name for the function within the functon body:

var x = function example() {
    console.log(typeof example); // "function"
};
x();
console.log(typeof example);     // "undefined"

然而,从 ES2015 开始,许多匿名"函数表达式创建带有名称的函数,而这早于各种现代 JavaScript 引擎非常聪明地从上下文推断名称.在 ES2015 中,匿名函数表达式会生成一个名为 boo 的函数.但是,即使使用 ES2015+ 语义,也不会创建自动标识符:

As of ES2015, though, a lot of "anonymous" function expressions create functions with names, and this was predated by various modern JavaScript engines being quite smart about inferring names from context. In ES2015, your anonymous function expression results in a function with the name boo. However, even with ES2015+ semantics, the automatic identifier is not created:

var obj = {
    x: function() {
       console.log(typeof x);   // "undefined"
       console.log(obj.x.name); // "x"
    },
    y: function y() {
       console.log(typeof y);   // "function"
       console.log(obj.y.name); // "y"
    }
};
obj.x();
obj.y();

函数名称的赋值是通过 SetFunctionName 抽象操作完成的规范中的各种操作.

The assignment fo the function's name is done with the SetFunctionName abstract operation used in various operations in the spec.

简短版本基本上是匿名函数表达式出现在诸如赋值或初始化之类的右侧的任何时候,例如:

The short version is basically any time an anonymous function expression appears on the right-hand side of something like an assignment or initialization, like:

var boo = function() { /*...*/ };

(或者可以是 letconst 而不是 var),或者

(or it could be let or const rather than var), or

var obj = {
    boo: function() { /*...*/ }
};

doSomething({
    boo: function() { /*...*/ }
});

(最后两个实际上是同一个东西),结果函数将有一个名称(boo,在示例中).

(those last two are really the same thing), the resulting function will have a name (boo, in the examples).

有一个重要且有意的例外:分配给现有对象的属性:

There's an important, and intentional, exception: Assigning to a property on an existing object:

obj.boo = function() { /*...*/ }; // <== Does not get a name

这是因为在添加新功能的过程中引发了信息泄漏问题;在我对另一个问题的回答中的详细信息此处.

This was because of information leak concerns raised when the new feature was going through the process of being added; details in my answer to another question here.

这篇关于为什么要使用命名函数表达式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆