Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
309 views
in Technique[技术] by (71.8m points)

javascript - 什么时候应该在ECMAScript 6中使用Arrow函数?(When should I use Arrow functions in ECMAScript 6?)

The question is directed at people who have thought about code style in the context of the upcoming ECMAScript 6 (Harmony) and who have already worked with the language.

(该问题针对的是那些在即将发布的ECMAScript 6(Harmony)中考虑过代码风格的人,并且已经在使用该语言。)

With () => {} and function () {} we are getting two very similar ways to write functions in ES6.

(通过() => {}function () {}我们得到了两种非常相似的方法来在ES6中编写函数。)

In other languages lambda functions often distinguish themselves by being anonymous, but in ECMAScript any function can be anonymous.

(在其他语言中,lambda函数通常通过匿名来区分自己,但是在ECMAScript中,任何函数都可以是匿名的。)

Each of the two types have unique usage domains (namely when this needs to either be bound explicitly or explicitly not be bound).

(每种类型都有独特的使用域(即当this需求已被明确约束或不明确的约束)。)

Between those domains there is a vast number of cases where either notation will do.

(在这些域之间,有很多情况下两种表示法都会起作用。)

Arrow functions in ES6 have at least two limitations:

(ES6中的箭头功能至少有两个限制:)

  • Don't work with new

    (不要使用new)

  • Fixed this bound to scope at initialisation

    (固定this绑定到初始化范围)

These two limitations aside, arrow functions could theoretically replace regular functions almost anywhere.

(除了这两个限制,箭头函数在理论上几乎可以替换任何地方的常规函数??。)

What is the right approach using them in practice?

(在实践中使用它们的正确方法是什么?)

Should arrow functions be used eg:

(应该使用箭头功能,例如:)

  • "everywhere they work", ie everywhere a function does not have to be agnostic about the this variable and we are not creating an object.

    (“无论它们在哪里工作”,即在每个地方函数都不必与this变量无关,我们也没有创建对象。)

  • only "everywhere they are needed", ie event listeners, timeouts, that need to be bound to a certain scope

    (仅需要绑定到特定范围的“任何需要它们的地方”,即事件侦听器,超时)

  • with 'short' functions but not with 'long' functions

    (具有“短”功能但不具有“长”功能)

  • only with functions that do not contain another arrow function

    (仅对于不包含另一个箭头功能的功能)

What I am looking for is a guideline to selecting the appropriate function notation in the future version of ECMAScript.

(我正在寻找的是在将来的ECMAScript版本中选择适当的功能符号的指南。)

The guideline will need to be clear, so that it can be taught to developers in a team, and to be consistent so that it does not require constant refactoring back and forth from one function notation to another.

(指南必须明确,以便可以向团队中的开发人员讲授,并且要保持一致,以便不需要从一个功能符号到另一个功能符号之间不断地进行重构。)

  ask by lyschoening translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

A while ago our team migrated all its code (a mid-sized AngularJS app) to JavaScript compiled using Traceur Babel .

(不久前,我们的团队将其所有代码(中型AngularJS应用程序)迁移到了使用 Traceur Babel编译的JavaScript。)

I'm now using the following rule of thumb for functions in ES6 and beyond:

(我现在对ES6及更高版本中的功能使用以下经验法则:)

  • Use function in the global scope and for Object.prototype properties.

    (在全局范围内和Object.prototype属性中使用function 。)

  • Use class for object constructors.

    (将class用于对象构造函数。)

  • Use => everywhere else.

    (在其他任何地方都使用=> 。)

Why use arrow functions almost everywhere?

(为什么几乎在所有地方都使用箭头功能?)

  1. Scope safety: When arrow functions are used consistently, everything is guaranteed to use the same thisObject as the root.

    (范围安全性:始终使用箭头功能时,可以确保所有内容都使用与根相同的thisObject 。)

    If even a single standard function callback is mixed in with a bunch of arrow functions there's a chance the scope will become messed up.

    (如果什至将单个标准函数回调与一堆箭头函数混在一起,则范围可能会混乱。)

  2. Compactness: Arrow functions are easier to read and write.

    (紧凑性:箭头功能更易于读写。)

    (This may seem opinionated so I will give a few examples further on).

    ((这似乎是自以为是的,所以我将进一步举例说明)。)

  3. Clarity: When almost everything is an arrow function, any regular function immediately sticks out for defining the scope.

    (清晰度:当几乎所有功能都是箭头功能时,任何常规function立即突出来定义范围。)

    A developer can always look up the next-higher function statement to see what the thisObject is.

    (开发人员始终可以查找更高一级的function语句,以查看thisObject是什么。)

Why always use regular functions on the global scope or module scope?

(为什么总是在全局作用域或模块作用域上使用常规函数?)

  1. To indicate a function that should not access the thisObject .

    (指示不应访问thisObject的函数。)

  2. The window object (global scope) is best addressed explicitly.

    (最好明确地处理window对象(全局范围)。)

  3. Many Object.prototype definitions live in the global scope (think String.prototype.truncate etc.) and those generally have to be of type function anyway.

    (许多Object.prototype定义都位于全局范围内(请考虑String.prototype.truncate等),并且无论如何,这些定义通常必须是类型function 。)

    Consistently using function on the global scope helps avoid errors.

    (在全局范围内一致使用function有助于避免错误。)

  4. Many functions in the global scope are object constructors for old-style class definitions.

    (全局范围内的许多函数都是旧式类定义的对象构造函数。)

  5. Functions can be named 1 .

    (函数可以命名为1 。)

    This has two benefits: (1) It is less awkward to write function foo(){} than const foo = () => {} — in particular outside other function calls.

    (这有两个好处:(1)与const foo = () => {}相比,编写function foo(){}更为const foo = () => {} —特别是在其他函数调用之外。)

    (2) The function name shows in stack traces.

    ((2)函数名称显示在堆栈跟踪中。)

    While it would be tedious to name every internal callback, naming all the public functions is probably a good idea.

    (虽然命名每个内部回调很麻烦,但是命名所有公共函数可能是一个好主意。)

  6. Function declarations are hoisted , (meaning they can be accessed before they are declared), which is a useful attribute in a static utility function.

    (函数声明是悬挂式的 (意味着可以在声明之前对其进行访问),这是静态实用程序函数中的一个有用属性。)


Object constructors

(对象构造函数)

Attempting to instantiate an arrow function throws an exception:

(尝试实例化箭头函数会引发异常:)

var x = () => {};
new x(); // TypeError: x is not a constructor

One key advantage of functions over arrow functions is therefore that functions double as object constructors:

(因此,与箭头函数相比,函数的一个关键优势是该函数还可以兼用作对象构造函数:)

function Person(name) {
    this.name = name;
}

However, the functionally identical 2 ES Harmony draft class definition is almost as compact:

(但是,功能上相同的2 ES Harmony 草案类定义几乎一样紧凑:)

class Person {
    constructor(name) {
        this.name = name;
    }
}

I expect that use of the former notation will eventually be discouraged.

(我希望最终不鼓励使用前一种表示法。)

The object constructor notation may still be used by some for simple anonymous object factories where objects are programmatically generated, but not for much else.

(有些对象仍可以将对象构造函数表示法用于简单的匿名对象工厂,在这些工厂中以编程方式生成对象,而其他方面则不多。)

Where an object constructor is needed one should consider converting the function to a class as shown above.

(在需要对象构造函数的地方,应考虑将函数转换为如上所述的class 。)

The syntax works with anonymous functions/classes as well.

(该语法也可用于匿名函数/类。)


Readability of arrow functions

(箭头功能的可读性)

The probably best argument for sticking to regular functions - scope safety be damned - would be that arrow functions are less readable than regular functions.

(坚持使用常规功能最好的论据(该死的示波器安全性)将是,箭头功能不如常规功能易读。)

If your code is not functional in the first place, then arrow functions may not seem necessary, and when arrow functions are not used consistently they look ugly.

(如果您的代码最初没有功能,那么箭头功能似乎就不是必需的,并且当箭头功能未得到一致使用时,它们看起来很丑陋。)

ECMAScript has changed quite a bit since ECMAScript 5.1 gave us the functional Array.forEach , Array.map and all of these functional programming features that have us use functions where for-loops would have been used before.

(自ECMAScript 5.1为我们提供了功能Array.forEachArray.map以及所有这些功能性编程功能(使我们使用以前曾使用过for循环的功能)以来,ECMAScript发生了很大变化。)

Asynchronous JavaScript has taken off quite a bit.

(异步JavaScript已经发展了很多。)

ES6 will also ship a Promise object, which means even more anonymous functions.

(ES6还将提供Promise对象,这意味着甚至更多的匿名功能。)

There is no going back for functional programming.

(函数式编程无可奈何。)

In functional JavaScript, arrow functions are preferable over regular functions.

(在功能性JavaScript中,箭头功能优于常规功能。)

Take for instance this (particularly confusing) piece of code 3 :

(以这段(特别是令人困惑的)代码3为例:)

function CommentController(articles) {
    this.comments = [];

    articles.getList()
        .then(articles => Promise.all(articles.map(article => article.comments.getList())))
        .then(commentLists => commentLists.reduce((a, b) => a.concat(b)));
        .then(comments => {
            this.comments = comments;
        })
}

The same piece of code with regular functions:

(具有常规功能的同一段代码:)

function CommentController(articles) {
    this.comments = [];

    articles.getList()
        .then(function (articles) {
            return Promise.all(articles.map(function (article) { 
                return article.comments.getList();
            }));
        })
        .then(function (commentLists) {
            return commentLists.reduce(function (a, b) {
                return a.concat(b); 
            });
        })
        .then(function (comments) {
            this.comments = comments;
        }.bind(this));
}

While any one of the arrow functions can be replaced by a standard function, there would be very little to gain from doing so.

(虽然任何箭头功能都可以用标准功能代替,但这样做几乎没有好处。)

Which version is more readable?

(哪个版本更具可读性?)

I would say the first one.

(我会说第一个。)

I think the question whether to use arrow functions or regular functions will become less relevant over time.

(我认为是使用箭头功能还是使用常规功能的问题随着时间的推移将变得越来越不重要。)

Most functions will either become class methods, which make away with the function keyword, or they will become classes.

(大多数函数要么成为类方法,而这些方法不再使用function关键字,要么成为类。)

Functions will remain in use for patching classes through the Object.prototype .

(函数将继续用于通过Object.prototype修补类。)

In the mean time I suggest reserving the function keyword for anything that should really be a class method or a class.

(同时,我建议为实际上应该是类方法或类的任何内容保留function关键字。)


Notes

(笔记)

  1. Named arrow functions have been deferred in the ES6 spec .

    (ES6规范中推迟了命名箭头功能。)

    They might still be added a future version.

    (他们可能仍会添加将来的版本。)

  2. According to the draft specification "Class declarations/expressions create a constructor function/prototype pair exactly as for function declarations" as long as a class does not use the extend keyword.

    (根据规范草案只要类不使用extend关键字, “类声明/表达式将创建与函数声明完全相同的构造函数/原型” 。)

    A minor difference is that class

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...