JavaScript 中“=>”(由等于和大于组成的箭头)是什么意思?

What's the meaning of "=>" (an arrow formed from equals & greater than) in JavaScript?

提问人:rpgs_player 提问时间:7/23/2014 最后编辑:MultiplyByZer0rpgs_player 更新时间:12/21/2022 访问量:401078

问:

我知道运算符的意思大于或等于,但我在一些源代码中看到过。该运算符的含义是什么?>==>

代码如下:

promiseTargetFile(fpParams, aSkipPrompt, relatedURI).then(aDialogAccepted => {
    if (!aDialogAccepted)
        return;

    saveAsType = fpParams.saveAsType;
    file = fpParams.file;

    continueSave();
}).then(null, Components.utils.reportError);
JavaScript 语法 ecmascript-6 arrow-functions

评论

5赞 Mistalis 12/23/2016
请参阅此链接,了解箭头函数

答:

25赞 Kyle Falconer 7/23/2014 #1

这就是 ECMAScript 6 中引入的“箭头函数表达式”。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/arrow_functions

出于历史目的(如果 wiki 页面稍后更改),它是:

与函数表达式相比,箭头函数表达式具有更短的语法,并且在词法上绑定了 this 值。箭头函数始终是匿名的。

评论

1赞 djechlin 7/23/2014
介意包含足够的信息,以便大多数读者不必向下钻取?
2赞 Kyle Falconer 7/23/2014
我链接到的 wiki 非常简洁地描述了它是什么:“与函数表达式相比,箭头函数表达式具有更短的语法,并且在词法上绑定了 this 值。箭头函数始终是匿名的。
1赞 Hanky Panky 7/23/2014
在此处将其添加为引用将真正帮助您回答。
621赞 elixenide 7/23/2014 #2

这是什么

这是一个箭头函数。箭头函数是 ECMAscript 6 引入的一种简短语法,其使用方式与使用函数表达式的方式类似。换句话说,您通常可以使用它们来代替 这样的表达式。但它们有一些重要的区别。例如,它们不绑定自己的值(请参阅下面的讨论)。function (foo) {...}this

箭头函数是 ECMAscript 6 规范的一部分。并非所有浏览器都支持它们,但截至 2018 年,Node v. 4.0+ 和大多数现代浏览器都部分或完全支持它们。(我在下面列出了部分支持浏览器)。

您可以在 Mozilla 文档中阅读有关箭头函数的更多信息

来自 Mozilla 文档:

与函数表达式相比,箭头函数表达式(也称为胖箭头函数)具有更短的语法,并且在词法上绑定 this 值(不绑定自己的 thisargumentssupernew.target)。箭头函数始终是匿名的。这些函数表达式最适合非方法函数,它们不能用作构造函数。

关于箭头函数中工作原理的说明this

箭头函数最方便的功能之一隐藏在上面的文本中:

箭头功能...词法绑定值(不绑定自己的值......thisthis

简单来说,这意味着箭头函数保留了其上下文中的值,并且没有自己的 .传统函数可以绑定自己的值,具体取决于它的定义和调用方式。这可能需要大量的体操,如 ,等,才能从一个函数访问或操作另一个函数。有关此主题的详细信息,请参阅 Mozilla 文档中的说明和示例thisthisthisself = this;this

示例代码

示例(也来自文档):

var a = [
  "We're up all night 'til the sun",
  "We're up all night to get some",
  "We're up all night for good fun",
  "We're up all night to get lucky"
];

// These two assignments are equivalent:

// Old-school:
var a2 = a.map(function(s){ return s.length });

// ECMAscript 6 using arrow functions
var a3 = a.map( s => s.length );

// both a2 and a3 will be equal to [31, 30, 31, 31]

兼容性注意事项

您可以在 Node 中使用箭头函数,但浏览器支持参差不齐。

浏览器对此功能的支持已经有了很大的改进,但对于大多数基于浏览器的用法来说,它仍然不够广泛。自 2017 年 12 月 12 日起,以下版本支持此功能:

  • Chrome (v. 45+)
  • Firefox (版本 22+)
  • 边缘 (v. 12+)
  • 歌剧 (v. 32+)
  • Android 浏览器 (v. 47+)
  • Opera Mobile (v. 33+)
  • 适用于 Android 的 Chrome (v. 47+)
  • 适用于 Android 的 Firefox (v. 44+)
  • Safari 浏览器 (v. 10+)
  • iOS Safari 浏览器 (v. 10.2+)
  • 三星互联网 (v. 5+)
  • 百度浏览器 (v. 7.12+)

不支持:

  • IE(第 11 版)
  • Opera Mini(至 v. 8.0)
  • Blackberry 浏览器(第 10 版)
  • IE Mobile(第 11 版)
  • UC Browser for Android (v. 11.4及之前版本)
  • QQ(1.2 至 v.1)

您可以在 CanIUse.com(无隶属关系)上找到更多(和更新)信息。

评论

4赞 mtyson 5/2/2017
TypeScript 似乎也支持它。
1赞 Addem 8/31/2018
看起来这是一个 lambda 表达式,是吗?
1赞 mbokil 11/5/2019
想提一下,在浏览器兼容性方面,我使用 ES6/ES7 箭头函数和其他与 IE11 本身不兼容的功能,但我使用 Gulp 或 Webpack 以及 Babel 将 ES6 转译为 ES5,以便它在 IE11 中工作。因此,如果你需要 IE11 支持,并且你不介意设置 Babel,那就去吧。
0赞 Donald Duck 4/14/2023
如今,所有现代浏览器都支持它们
0赞 elixenide 6/21/2023
@DonaldDuck 没错,但该页面还显示并非所有用户都在使用现代浏览器。大约 96.2% 的用户使用支持箭头功能的浏览器,但这不是 100%。根据上下文,这 3.8% 可能是也可能不是避免特定语言功能的好理由。(不要误会我的意思;就我个人而言,我会说这已经足够接近并且涵盖了所有合法用户。但是 YMMV。
8赞 Mritunjay 7/23/2014 #3

我读过,这是 in 的象征Arrow FunctionsES6

var a2 = a.map(function(s){ return s.length });

使用可以写成Arrow Function

var a3 = a.map( s => s.length );

MDN 文档

88赞 brbcoding 7/23/2014 #4

这被称为箭头函数,是 ECMAScript 2015 规范的一部分......

var foo = ['a', 'ab', 'abc'];

var bar = foo.map(f => f.length);

console.log(bar); // 1,2,3

语法比前面的语法更短:

// < ES6:
var foo = ['a', 'ab', 'abc'];

var bar = foo.map(function(f) {
  return f.length;
});
console.log(bar); // 1,2,3

演示

另一个很棒的事情是词汇......通常,你会做这样的事情:this

function Foo() {
  this.name = name;
  this.count = 0;
  this.startCounting();
}

Foo.prototype.startCounting = function() {
  var self = this;
  setInterval(function() {
    // this is the Window, not Foo {}, as you might expect
    console.log(this); // [object Window]
    // that's why we reassign this to self before setInterval()
    console.log(self.count);
    self.count++;
  }, 1000)
}

new Foo();

但这可以用这样的箭头重写:

function Foo() {
  this.name = name;
  this.count = 0;
  this.startCounting();
}

Foo.prototype.startCounting = function() {
  setInterval(() => {
    console.log(this); // [object Object]
    console.log(this.count); // 1, 2, 3
    this.count++;
  }, 1000)
}

new Foo();

演示

MDN
更多关于语法

对于更多内容,这里有一个关于何时使用箭头函数的很好的答案。

评论

1赞 Wavesailor 10/17/2018
最好更新演示以使用 esfiddle.net因为 es6fiddle.net 不再运行
22赞 Bart Calixto 7/23/2014 #5

只是为了添加另一个示例,说明lambda可以在不使用map的情况下执行哪些操作:

a = 10
b = 2

var mixed = (a,b) => a * b; 
// OR
var mixed = (a,b) => { (any logic); return a * b };

console.log(mixed(a,b)) 
// 20
2赞 JMM 9/30/2015 #6

正如所有其他答案已经说过的那样,它是 ES2015 箭头函数语法的一部分。更具体地说,它不是一个运算符,而是一个标点符号,用于将参数与正文分开:.例如。ArrowFunction : ArrowParameters => ConciseBody(params) => { /* body */ }

14赞 Oriol 10/12/2015 #7

正如其他人所说,创建函数是一种新的语法。

但是,这种功能与普通功能不同:

  • 它们绑定了值。正如规范所解释的this

    ArrowFunction 不定义 、 、 或 的本地绑定。对 、 、 或 ArrowFunction 内的任何引用都必须 解析为词法封闭环境中的绑定。通常 这将是一个立即封闭的功能环境 功能。argumentssuperthisnew.targetargumentssuperthisnew.target

    即使 ArrowFunction 可能包含对 的引用,也 在步骤 4 中创建的函数对象不是由 执行 MakeMethod。引用的 ArrowFunction 始终包含在非 ArrowFunction 中,并且需要 要实现的状态可通过以下范围访问: 由 ArrowFunction 的函数对象捕获。supersupersuper

  • 它们是非构造函数。

    这意味着它们没有 [[Construct]] 内部方法,因此无法实例化,例如

    var f = a => a;
    f(123);  // 123
    new f(); // TypeError: f is not a constructor
    
29赞 Toby Mellor 4/26/2017 #8

这些是箭头函数

也称为胖箭头函数。它们是编写函数表达式的一种简洁明了的方法,例如 .function() {}

箭头函数可以消除定义函数时的需要,和。它们是单行代码,类似于 Java 或 Python 中的 Lambda 表达式。functionreturn{}

不带参数的示例

const queue = ['Dave', 'Sarah', 'Sharon'];
const nextCustomer = () => queue[0];

console.log(nextCustomer()); // 'Dave'

如果需要在同一个箭头函数中进行多个语句,则需要在本例中将大括号括起来。在这种情况下,不能省略 return 语句。queue[0]{}

具有 1 个参数的示例

const queue = ['Dave', 'Sarah', 'Sharon'];
const addCustomer = name => {
  queue.push(name);
};

addCustomer('Toby');

console.log(queue); // ['Dave', 'Sarah', 'Sharon', 'Toby']

您可以从上面省略。{}

当存在单个参数时,可以省略参数两边的括号。()

具有多个参数的示例

const addNumbers = (x, y) => x + y

console.log(addNumbers(1, 5)); // 6

一个有用的例子

const fruits = [
    { name: 'Apple', price: 2 },
    { name: 'Bananna', price: 3 },
    { name: 'Pear', price: 1 }
];

如果我们想获得单个数组中每个水果的价格,在 ES5 中,我们可以这样做:

fruits.map(function(fruit) {
    return fruit.price;
}); // [2, 3, 1]

在 ES6 中,有了新的箭头函数,我们可以更简洁地做到这一点:

fruits.map(fruit => fruit.price); // [2, 3, 1]

有关箭头函数的其他信息,请参阅此处

6赞 Hitesh Sahu 11/2/2017 #9

使用 Arrowfunction 添加简单的 CRUD 示例

 //Arrow Function
 var customers   = [
   {
     name: 'Dave',
     contact:'9192631770'
   },
   {
     name: 'Sarah',
     contact:'9192631770'
   },
   {
     name: 'Akhil',
     contact:'9928462656' 
   }],

// No Param READ
 getFirstCustomer = () => { 
   console.log(this);
   return customers[0];
 };
  console.log("First Customer "+JSON.stringify(getFirstCustomer())); // 'Dave' 

   //1 Param SEARCH
  getNthCustomer = index=>{
    if( index>customers.length)
    {
     return  "No such thing";
   }
   else{
       return customers[index];
     } 
  };
  console.log("Nth Customer is " +JSON.stringify(getNthCustomer(1))); 

   //2params ADD
  addCustomer = (name, contact)=> customers.push({
     'name': name,
     'contact':contact
    });
  addCustomer('Hitesh','8888813275');
  console.log("Added Customer "+JSON.stringify(customers)); 

  //2 param UPDATE
  updateCustomerName = (index, newName)=>{customers[index].name= newName};
  updateCustomerName(customers.length-1,"HiteshSahu");
  console.log("Updated Customer "+JSON.stringify(customers));

  //1 param DELETE
  removeCustomer = (customerToRemove) => customers.pop(customerToRemove);
  removeCustomer(getFirstCustomer());
  console.log("Removed Customer "+JSON.stringify(customers)); 
1赞 Willem van der Veen 8/29/2018 #10

ES6箭头功能:

在 javascript 中,是箭头函数表达式的符号。箭头函数表达式没有自己的绑定,因此不能用作构造函数。例如:=>this

var words = 'hi from outside object';

let obj = {
  words: 'hi from inside object',
  talk1: () => {console.log(this.words)},
  talk2: function () {console.log(this.words)}
}

obj.talk1();  // doesn't have its own this binding, this === window
obj.talk2();  // does have its own this binding, this is obj

箭头函数使用规则:

  • 如果只有一个参数,则可以省略参数的括号。
  • 如果返回一个表达式并在同一行上执行此操作,则可以省略 和 语句{}return

例如:

let times2 = val => val * 2;  
// It is on the same line and returns an expression therefore the {} are ommited and the expression returns implictly
// there also is only one argument, therefore the parentheses around the argument are omitted

console.log(times2(3));

7赞 Shivprasad Koirala 2/10/2019 #11

用符号 (=>) 表示的箭头函数可帮助您创建匿名函数和方法。这会导致更短的语法。例如,下面是一个简单的“Add”函数,它返回两个数字的相加。

function Add(num1 , num2 ){
return num1 + num2;
}

通过使用“Arrow”语法,上述函数变得更短,如下所示。

enter image description here

上面的代码有两个部分,如上图所示: -

输入: — 此部分指定匿名函数的输入参数。

逻辑: — 此部分位于符号“=>”之后。本节有实际函数的逻辑。

许多开发人员认为箭头函数使你的语法更短、更简单,从而使你的代码具有可读性。

如果你相信上面的句子,那么让我向你保证这是一个神话。如果您想一想,正确编写的带有名称的函数比使用箭头符号在一行中创建的神秘函数更具可读性。

箭头函数的主要用途是确保代码在 调用方上下文。

请参阅下面的代码,其中定义了一个全局变量“context”,该全局变量在函数“SomeOtherMethod”中访问,该函数从其他方法“SomeMethod”调用。

这个“SomeMethod”具有局部“context”变量。现在,由于“SomeOtherMethod”是从“SomeMethod”调用的,我们希望它显示“本地上下文”,但它显示“全局上下文”。

var context = “global context”;

function SomeOtherMethod(){
alert(this.context);
}

function SomeMethod(){
this.context = “local context”;
SomeOtherMethod();
}

var instance = new SomeMethod();

但是,如果使用箭头函数替换调用,它将显示“本地上下文”。

var context = "global context";
   
    function SomeMethod(){
        this.context = "local context";
        SomeOtherMethod = () => {
            alert(this.context);
        }
        SomeOtherMethod();
    }
    var instance = new SomeMethod();

我鼓励您阅读此链接( JavaScript 中的箭头函数 ),它解释了 javascript 上下文的所有场景,以及在哪些场景中不尊重调用方上下文。

您还可以在我制作的这个 youtube 视频中看到使用 javascript 的 Arrow 函数的演示,该视频实际上演示了术语 Context。

评论

1赞 Reddspark 3/23/2023
更好的答案之一。虽然我会从句子 '=> 开始,但这是一种编写函数的较短方法,该函数接受一些参数(在左侧),然后对其进行执行操作(在右侧)。
9赞 gman 3/13/2019 #12

对其他答案不满意。截至 2019 年 3 月 13 日,投票最多的答案实际上是错误的。

含义的简短版本是,它是编写函数的快捷方式,用于将其绑定到当前=>this

const foo = a => a * 2;

实际上是

const foo = function(a) { return a * 2; }.bind(this);

你可以看到所有被缩短的东西。我们不需要,也不需要,甚至不需要大括号或括号functionreturn.bind(this)

箭头函数的一个稍长的示例可能是

const foo = (width, height) => {
  const area = width * height;
  return area;
};

表明如果我们想要函数的多个参数,我们需要括号,如果我们想写多个表达式,我们需要大括号和一个显式。return

理解这部分很重要,这是一个很大的话题。这与 JavaScript 中的含义有关。.bindthis

ALL 函数都有一个称为 的隐式参数。调用函数时的设置方式取决于该函数的调用方式。thisthis

function foo() { console.log(this); }

如果正常调用

function foo() { console.log(this); }
foo();

this将是全局对象。

如果您处于严格模式

`use strict`;
function foo() { console.log(this); }
foo();

// or

function foo() {
   `use strict`;
   console.log(this);
 }
foo();

这将是undefined

您可以直接使用 或thiscallapply

function foo(msg) { console.log(msg, this); }

const obj1 = {abc: 123}
const obj2 = {def: 456}

foo.call(obj1, 'hello');  // prints Hello {abc: 123}
foo.apply(obj2, ['hi']);  // prints Hi {def: 456}

您还可以使用点运算符进行隐式设置this.

function foo(msg) { console.log(msg, this); }
const obj = {
   abc: 123,
   bar: foo,
}
obj.bar('Hola');  // prints Hola {abc:123, bar: f}

当您想将函数用作回调或侦听器时,会出现问题。您创建类并希望分配一个函数作为访问该类实例的回调。

class ShowName {
  constructor(name, elem) {
    this.name = name;
    elem.addEventListener('click', function() {
       console.log(this.name);  // won't work
    }); 
  }
}

上面的代码将不起作用,因为当元素触发事件并调用函数时,该值将不是类的实例。this

解决该问题的一种常见方法是使用.bind

class ShowName {
  constructor(name, elem) {
    this.name = name;
    elem.addEventListener('click', function() {
       console.log(this.name); 
    }.bind(this); // <=========== ADDED! ===========
  }
}

因为箭头语法的作用与我们可以编写的相同

class ShowName {
  constructor(name, elem) {
    this.name = name;
    elem.addEventListener('click',() => {
       console.log(this.name); 
    });
  }
}

bind有效地制作了一个新函数。如果不存在,你基本上可以像这样制作自己的bind

function bind(functionToBind, valueToUseForThis) {
  return function(...args) {
    functionToBind.call(valueToUseForThis, ...args);
  };
}

在没有 spread 运算符的旧 JavaScript 中,它将是

function bind(functionToBind, valueToUseForThis) {
  return function() {
    functionToBind.apply(valueToUseForThis, arguments);
  };
}

理解该代码需要了解闭包,但简短的版本是创建一个新函数,该函数始终使用绑定到它的值调用原始函数。箭头函数做同样的事情,因为它们是bindthisbind(this)

2赞 SlowLearner 9/17/2019 #13

正如其他人所说,常规(传统)函数使用来自调用函数的对象(例如,单击的按钮)。相反,箭头函数使用定义函数的对象。thisthis

考虑两个几乎相同的函数:

regular = function() {
  ' Identical Part Here;
}


arrow = () => {
  ' Identical Part Here;
}

下面的代码片段演示了每个函数所表示的内容之间的根本区别。常规函数输出,而箭头函数输出。this[object HTMLButtonElement][object Window]

<html>
 <button id="btn1">Regular: `this` comes from "this button"</button>
 <br><br>
 <button id="btn2">Arrow: `this` comes from object that defines the function</button>
 <p id="res"/>

 <script>
  regular = function() {
    document.getElementById("res").innerHTML = this;
  }

  arrow = () => {
    document.getElementById("res").innerHTML = this;
  }

  document.getElementById("btn1").addEventListener("click", regular);
  document.getElementById("btn2").addEventListener("click", arrow);
 </script>
</html>

1赞 gagarine 7/22/2021 #14

JavaScript 箭头函数大致相当于 python 中的 lambda 函数或 Ruby 中的块。这些是匿名函数,具有自己的特殊语法,并在其封闭范围的上下文中运行。这意味着他们没有自己的“this”,而是从直接封闭函数访问那个。

ECMA标准来看:

ArrowFunction 不定义参数superthisnew.target 的本地绑定。在 ArrowFunction 中对参数、super、this 或 new.target 的任何引用都必须解析为 在词法封闭环境中进行绑定。通常,这将是 立即封闭函数的函数环境。

通常你可以读到“箭头函数表达式是传统函数表达式的紧凑替代品”,这是不正确的。箭头函数不是传统函数的简写,它们的行为与传统函数不同。

语法

// Traditional Function
// Create their own scope inside the function
function (a){
  return a + 100;
}

// Arrow Function 
// Do NOT create their own scope
// (Each step along the way is a valid "arrow function")

// 1. Remove the word "function" and place arrow between the argument and opening body bracket
(a) => {
  return a + 100;
}

// 2. Remove the body braces and word "return" -- the return is implied.
(a) => a + 100;

// 3. Remove the argument parentheses (only valid with exactly one argument)
a => a + 100;

评论

0赞 Bergi 7/22/2021
JS 中没有函数具有“固定数量的参数”
1赞 gagarine 7/22/2021
@Bergi是的,你是对的。我想说“接受论点的语法”,但这是误导性的。我认为现在的代码片段是不言自明的。
0赞 Bergi 7/22/2021
顺便说一句,它们也有自己的(可变)范围。它们没有单独的值,通常称为上下文this
1赞 gagarine 7/24/2021
@Bergi关于范围的固定问题