“箭头函数"和“函数"是否等效/可互换?

编程入门 行业动态 更新时间:2024-10-28 02:23:44
本文介绍了“箭头函数"和“函数"是否等效/可互换?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

ES2015 中的箭头函数提供了更简洁的语法.

Arrow functions in ES2015 provide a more concise syntax.

  • 我现在可以用箭头函数替换我所有的函数声明/表达式吗?
  • 我需要注意什么?

示例:

构造函数

function User(name) { this.name = name; } // vs const User = name => { this.name = name; };

原型方法

User.prototype.getName = function() { return this.name; }; // vs User.prototype.getName = () => this.name;

对象(文字)方法

const obj = { getName: function() { // ... } }; // vs const obj = { getName: () => { // ... } };

回调

setTimeout(function() { // ... }, 500); // vs setTimeout(() => { // ... }, 500);

可变函数

function sum() { let args = [].slice.call(arguments); // ... } // vs const sum = (...args) => { // ... };

推荐答案

tl;dr: 不! 箭头函数和函数声明/表达式不是等价的,不能是盲目更换.如果您要替换的函数不使用this、arguments并且没有使用new调用,则是.

tl;dr: No! Arrow functions and function declarations / expressions are not equivalent and cannot be replaced blindly. If the function you want to replace does not use this, arguments and is not called with new, then yes.

通常情况下:这取决于.箭头函数与函数声明/表达式有不同的行为,所以让我们先看看它们的区别:

As so often: it depends. Arrow functions have different behavior than function declarations / expressions, so let's have a look at the differences first:

1.词法 this 和 arguments

1. Lexical this and arguments

箭头函数没有自己的this 或arguments 绑定.相反,这些标识符像任何其他变量一样在词法范围内解析.这意味着在箭头函数内部,this 和arguments 指的是环境中this 和arguments 的值箭头函数定义在(即箭头函数之外"):

Arrow functions don't have their own this or arguments binding. Instead, those identifiers are resolved in the lexical scope like any other variable. That means that inside an arrow function, this and arguments refer to the values of this and arguments in the environment the arrow function is defined in (i.e. "outside" the arrow function):

// Example using a function expression function createObject() { console.log('Inside `createObject`:', this.foo); return { foo: 42, bar: function() { console.log('Inside `bar`:', this.foo); }, }; } createObject.call({foo: 21}).bar(); // override `this` inside createObject

// Example using a arrow function function createObject() { console.log('Inside `createObject`:', this.foo); return { foo: 42, bar: () => console.log('Inside `bar`:', this.foo), }; } createObject.call({foo: 21}).bar(); // override `this` inside createObject

在函数表达式的情况下,this 指的是在createObject 中创建的对象.在箭头函数的情况下,this指的是createObject本身的this.

In the function expression case, this refers to the object that was created inside the createObject. In the arrow function case, this refers to this of createObject itself.

如果你需要访问当前环境的this,这使得箭头函数很有用:

This makes arrow functions useful if you need to access the this of the current environment:

// currently common pattern var that = this; getData(function(data) { that.data = data; }); // better alternative with arrow functions getData(data => { this.data = data; });

注意这也意味着不可能用.bind设置箭头函数的this或.call.

Note that this also means that is not possible to set an arrow function's this with .bind or .call.

如果你对this不是很熟悉,可以考虑阅读

If you are not very familiar with this, consider reading

  • MDN - 这个
  • YDKJS - 这个 &对象原型

2.new

ES2015 区分了可调用的函数和可构造的函数.如果函数是可构造的,则可以使用 new 调用它,即 new User().如果一个函数是可调用的,它可以在没有 new 的情况下被调用(即正常的函数调用).

ES2015 distinguishes between functions that are callable and functions that are constructable. If a function is constructable, it can be called with new, i.e. new User(). If a function is callable, it can be called without new (i.e. normal function call).

通过函数声明/表达式创建的函数既可构造又可调用.箭头函数(和方法)只能调用.class 构造函数只能构造.

Functions created through function declarations / expressions are both constructable and callable. Arrow functions (and methods) are only callable. class constructors are only constructable.

如果您尝试调用不可调用的函数或构造不可构造的函数,则会出现运行时错误.

If you are trying to call a non-callable function or to construct a non-constructable function, you will get a runtime error.

知道了这一点,我们可以陈述以下内容.

Knowing this, we can state the following.

可替换:

  • 不使用this 或arguments 的函数.
  • 与 .bind(this) 一起使用的函数
  • Functions that don't use this or arguments.
  • Functions that are used with .bind(this)

不可替换:

  • 构造函数
  • 添加到原型中的函数/方法(因为它们通常使用this)
  • 可变参数函数(如果它们使用arguments(见下文))
  • 生成器函数,需要 function* 符号
  • Constructor functions
  • Function / methods added to a prototype (because they usually use this)
  • Variadic functions (if they use arguments (see below))
  • Generator functions, which require the function* notation

让我们用你的例子仔细看看这个:

Lets have a closer look at this using your examples:

构造函数

这行不通,因为箭头函数不能用 new 调用.继续使用函数声明/表达式或使用 class.

This won't work because arrow functions cannot be called with new. Keep using a function declaration / expression or use class.

原型方法

很可能不是,因为原型方法通常使用 this 来访问实例.如果他们不使用this,那么您可以替换它.但是,如果您主要关心简洁的语法,请使用 class 及其简洁的方法语法:

Most likely not, because prototype methods usually use this to access the instance. If they don't use this, then you can replace it. However, if you primarily care for concise syntax, use class with its concise method syntax:

class User { constructor(name) { this.name = name; } getName() { return this.name; } }

对象方法

类似于对象字面量中的方法.如果方法想通过this引用对象本身,继续使用函数表达式,或者使用新的方法语法:

Similarly for methods in an object literal. If the method wants to reference the object itself via this, keep using function expressions, or use the new method syntax:

const obj = { getName() { // ... }, };

回调

这取决于.如果您为外部 this 设置别名或正在使用 .bind(this),则绝对应该替换它:

It depends. You should definitely replace it if you are aliasing the outer this or are using .bind(this):

// old setTimeout(function() { // ... }.bind(this), 500); // new setTimeout(() => { // ... }, 500);

但是:如果调用回调的代码显式地将 this 设置为一个特定的值,这在事件处理程序(尤其是 jQuery)中经常发生,并且回调使用this(或arguments),你不能使用箭头函数!

But: If the code which calls the callback explicitly sets this to a specific value, as is often the case with event handlers, especially with jQuery, and the callback uses this (or arguments), you cannot use an arrow function!

可变函数

由于箭头函数没有自己的参数,您不能简单地用箭头函数替换它们.但是,ES2015 引入了使用 arguments 的替代方法:休息参数.

Since arrow functions don't have their own arguments, you cannot simply replace them with an arrow function. However, ES2015 introduces an alternative to using arguments: the rest parameter.

// old function sum() { let args = [].slice.call(arguments); // ... } // new const sum = (...args) => { // ... };

相关问题:


Related question:

  • 什么时候应该在 ECMAScript 6 中使用箭头函数?
  • ES6 箭头函数是否有自己的参数?
  • ES6 箭头函数和使用 Function.prototype.bind 绑定的函数之间有什么区别(如果有的话)?
  • 如何使用箭头函数(公共类字段)作为类方法?

更多资源:

  • MDN - 箭头函数
  • YDKJS - 箭头函数

更多推荐

“箭头函数"和“函数"是否等效/可互换?

本文发布于:2023-10-07 20:05:53,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1470405.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:函数   箭头   quot

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!