JavaScript中“ =>”(等于或大于的箭头)的含义是什么?


444

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

这是代码:

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

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

    continueSave();
}).then(null, Components.utils.reportError);

5
有关箭头功能,请参见此链接。
Mistalis '16

Answers:


546

这是什么

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

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

您可以在Mozilla文档的箭头功能中阅读更多内容

从Mozilla文档中:

相比箭头函数表达式(也称为脂肪箭头功能)具有更短的语法函数表达式和词法结合this值(不结合其自身的thisargumentssuper,或new.target)。箭头函数始终是匿名的。这些函数表达式最适合于非方法函数,因此不能用作构造函数。

关于this箭头功能如何工作的注释

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

箭头函数...按词法绑定this值(不绑定自己的值this...)

用更简单的术语表示,箭头功能保留了this上下文中的值,而没有自己的值this。传统函数可以绑定自己的this值,具体取决于如何定义和调用它。这可能需要大量的体操运动,例如self = this;等,才能this从另一个功能中访问或操作另一个功能。有关此主题的更多信息,请参见Mozilla文档中的解释和示例

范例程式码

示例(同样来自文档):

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+)
  • Chrome for Android(v。47+)
  • 适用于Android的Firefox(版本44或更高)
  • Safari(10岁以上)
  • iOS Safari(10.2以上版本)
  • 三星互联网(v。5+)
  • 百度浏览器(7.12+)

不支持:

  • IE(通过第11版)
  • Opera Mini(通过8.0版)
  • 黑莓浏览器(通过第10版)
  • IE Mobile(通过v。11)
  • 适用于Android的UC浏览器(通过11.4版)
  • QQ(通过1.2版)

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


3
TypeScript也似乎支持它。
mtyson '17年

1
看起来这是一个lambda表达式,是吗?
Addem

1
在浏览器兼容性方面想提一下,我使用ES6 / ES7箭头功能和其他与IE11本机不兼容的功能,但是我使用Gulp或Webpack以及Babel将ES6转换为ES5,因此它可以在IE11中使用。因此,如果您需要IE11支持,并且不介意设置Babel,请继续使用它。
mbokil

76

这被称为箭头功能,是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
有关语法的更多信息

有关更多信息,这是何时使用箭头功能一个很好的答案。


最好更新演示以使用esfiddle.net,因为es6fiddle.net不再运行
Wavesailor

25

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

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/arrow_functions

出于历史目的(如果Wiki页面稍后更改),则为:

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


1
介意包含足够的信息,以便大多数读者不必深入研究吗?
djechlin

2
我链接到的Wiki非常简洁地描述了它的含义:“箭头函数表达式的语法比函数表达式短,并且在词法上绑定了此值。箭头函数始终是匿名的。”
Kyle Falconer 2014年

1
在此处添加报价确实可以帮助您解答。
Hanky Panky 2014年

22

这些是箭头功能

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

箭头功能可以去除的需要functionreturn{}定义函数时。它们是一排,类似于Java或Python中的Lambda表达式。

没有参数的例子

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

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

如果需要在同一个Arrow Function中执行多个语句,则在此示例中,您需要将它们包装queue[0]在curley方括号中{}。在这种情况下,return语句不能省略。

带有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]

可以在此处找到有关箭头功能的更多信息

浏览器兼容性

  • IE:尚不支持
  • 边缘:12+(所有版本)
  • Firefox:22岁以上
  • 铬:45+
  • Safari:10岁以上
  • iOS Safari:10.2以上
  • Android浏览器:56+

其他有关浏览器兼容性的最新信息,请参见此处。


21

只是要添加另一个示例,说明lambda无需使用地图即可执行的操作:

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

13

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

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

  • 他们约束this价值。如规格说明所述

    一个ArrowFunction没有定义本地绑定argumentssuperthis,或new.target。任何参照argumentssuperthis,或new.target的内ArrowFunction必须解析为在词法封闭环境的结合。通常,这将是立即封闭函数的函数环境。

    即使ArrowFunction可能包含对它的引用super,也不会通过执行MakeMethod将步骤4中创建的函数对象制成方法。引用的ArrowFunctionsuper 始终包含在非ArrowFunction中,并且super可以通过ArrowFunction的函数对象捕获的范围来访问实现的必要状态。

  • 他们是非构造函数。

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

    var f = a => a;
    f(123);  // 123
    new f(); // TypeError: f is not a constructor

8

我读过,这是象征Arrow FunctionsES6

这个

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

使用Arrow Function可以写成

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

MDN文件


6

使用Arrow功能添加简单的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)); 

4

对其他答案不满意。截至2019/3/13为止,票数最高的答案实际上是错误的。

什么样的短简洁版本=>指的是它的快捷方式写一个函数它结合当前this

const foo = a => a * 2;

实际上是

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

您可以看到所有缩短的内容。我们并不需要function,也不return也不.bind(this)甚至也不是大括号或圆括号

箭头功能的稍长示例可能是

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

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

了解这一.bind部分很重要,这是一个大话题。它与thisJavaScript中的含义有关。

所有函数都有一个称为的隐式参数this。怎么样this调用函数时设置取决于该函数的调用方式。

采取

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

您可以this使用call或直接设置apply

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(funcitonToBind, valueToUseForThis) {
  return function(...args) {
    functionToBind.call(valueToUseForThis, ...args);
  };
}

在没有传播运算符的旧版JavaScript中,

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

了解该代码需要了解闭包,但简短的版本是bind一个新函数,该函数始终使用this绑定到其的值来调用原始函数。箭头功能执行相同的操作,因为它们是bind(this)


2

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


1

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));


1

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

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

如下所示,通过使用“箭头”语法,上述功能变得更短。

在此处输入图片说明

上面的代码由两部分组成,如上图所示:-

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

逻辑:—本节位于符号“ =>”之后。本节具有实际功能的逻辑。

许多开发人员认为箭头功能使您的语法更短,更简单,从而使您的代码更具可读性。

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

箭头功能的主要用途是确保代码在调用方上下文中运行。

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

此“ SomeMethod”具有本地“ context”变量。现在,因为从“ SomeMethod”调用了“ SomeOtherMethod”,我们希望它显示“ local context”,但显示“ global context”。

var context = global context”;

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

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

var instance = new SomeMethod();

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

var context = "global context";

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

我鼓励您阅读此链接(JavaScript中的Arrow函数),该链接说明了javascript上下文的所有情况,以及在哪种情况下都不尊重调用者上下文。

您还可以在此youtube视频中看到带有JavaScriptArrow函数演示,该演示实际上演示了上下文。


0

如其他人所述,常规(传统)功能会this从调用该功能的对象中使用(例如,被单击的按钮)。相反,箭头函数使用this的是定义函数的对象。

考虑两个几乎相同的功能:

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>

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.