Что означает «=>» (стрелка, образованная из «равно и больше») в JavaScript?

444

Я знаю, что >=оператор означает больше или равно, но я видел =>в некотором исходном коде. В чем смысл этого оператора?

Вот код:

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

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

    continueSave();
}).then(null, Components.utils.reportError);
rpgs_player
источник
5
Смотрите эту ссылку о функциях стрелок .
Мисталис

Ответы:

547

Что это

Это функция стрелки. Функции со стрелками - это короткий синтаксис, введенный в ECMAscript 6, который можно использовать аналогично тому, как вы использовали бы выражения функций. Другими словами, вы часто можете использовать их вместо таких выражений, как function (foo) {...}. Но у них есть некоторые важные различия. Например, они не связывают свои собственные значенияthis (см. Обсуждение ниже).

Функции стрелок являются частью спецификации ECMAscript 6. Они еще не поддерживаются во всех браузерах, но частично или полностью поддерживаются в Node v. 4.0+ и в большинстве современных браузеров, используемых по состоянию на 2018. (Ниже приведен частичный список поддерживаемых браузеров).

Вы можете прочитать больше в документации по функциям стрелок в Mozilla .

Из документации Mozilla:

Функция стрелка выражение (также известное как жир функция стрелки) имеет более короткий синтаксис по сравнению с функциональными выражениями и лексический связывает thisзначение (не связывает свой собственные this, arguments, superили new.target). Функции стрелок всегда анонимны. Эти функциональные выражения лучше всего подходят для функций, не относящихся к методам, и их нельзя использовать в качестве конструкторов.

Замечание о том, как thisработает функция Arrow

Одна из наиболее удобных функций функции со стрелкой скрыта в тексте выше:

Функция стрелки ... лексически связывает 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, но поддержка браузера не совсем корректна.

Браузерная поддержка этой функциональности значительно улучшилась, но она все еще недостаточно распространена для большинства применений на основе браузера. По состоянию на 12 декабря 2017 года он поддерживается в текущих версиях:

  • Chrome (v. 45+)
  • Firefox (v. 22+)
  • Край (против 12+)
  • Опера (ст. 32+)
  • Браузер Android (версия 47+)
  • Opera Mobile (версия 33+)
  • Chrome для Android (версия 47+)
  • Firefox для Android (версия 44+)
  • Safari (версия 10+)
  • iOS Safari (версия 10.2+)
  • Интернет Samsung (версия 5+)
  • Baidu Browser (v. 7.12+)

Не поддерживается в:

  • IE (до ст. 11)
  • Opera Mini (до версии 8.0)
  • Blackberry Browser (до ст. 10)
  • IE Mobile (до версии 11)
  • UC Browser для Android (до версии 11.4)
  • QQ (до версии 1.2)

Вы можете найти более (и более актуальную) информацию на CanIUse.com (без принадлежности).

elixenide
источник
3
TypeScript также, кажется, поддерживает это.
Мтисон
1
Похоже, это лямбда-выражение, да?
Дополнение
1
Хотелось бы упомянуть о совместимости браузера: я использую функции стрелок ES6 / ES7 и другие функции, изначально не совместимые с IE11, но я использую Gulp или Webpack вместе с Babel для переноса ES6 в ES5, чтобы он работал в IE11. Так что если вам нужна поддержка IE11 и вы не против настроить Babel, тогда сделайте это.
Мбокил
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

DEMO

Другая удивительная вещь лексическая 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();

DEMO

MDN
Подробнее о синтаксисе

Более того, вот довольно хороший ответ, когда использовать функции стрелок.

brbcoding
источник
Было бы неплохо обновить демо-версии для использования esfiddle.net, так как es6fiddle.net больше не работает
Wavesailor
25

Это будет «выражение функции стрелки», введенное в ECMAScript 6.

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

Для исторических целей (если страница вики меняется позже), это:

Выражение функции со стрелкой имеет более короткий синтаксис по сравнению с выражениями функции и лексически связывает значение this. Функции стрелок всегда анонимны.

Кайл Фалконер
источник
1
Не забудьте включить достаточно информации, чтобы большинству читателей не приходилось углубляться?
Джечлин
2
Вики, на которую я очень кратко ссылался, описывает, что это такое: «Выражение функции со стрелкой имеет более короткий синтаксис по сравнению с выражениями функций и лексически связывает это значение. Функции со стрелками всегда анонимны».
Кайл Фалконер,
1
Добавление в качестве цитаты здесь действительно поможет вашему ответу.
Ханки Панки
22

Это функции стрелок

Также известен как Fat Arrow Functions . Это простой и понятный способ написания функциональных выражений, например function() {}.

Стрелка функции может удалить необходимость function, returnи{} при определении функций. Они являются однострочными, похожими на лямбда-выражения в Java или Python.

Пример без параметров

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

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

Если в одной и той же функции стрелки необходимо сделать несколько операторов, в этом примере необходимо 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]

Дополнительную информацию о функциях со стрелками можно найти здесь .

Совместимость браузера

  • IE: пока не поддерживается
  • Край: 12+ (все версии)
  • Firefox: 22+
  • Хром: 45+
  • Сафари: 10+
  • iOS Safari: 10.2+
  • Браузер Android: 56+

Дополнительную актуальную информацию о совместимости браузера можно найти здесь

Тоби Меллор
источник
21

просто чтобы добавить еще один пример того, что лямбда может делать без использования карты:

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 не определяет локальные привязки для arguments, super, this, или new.target. Любая ссылка на arguments, super, thisили в new.targetпределах ArrowFunction должна решить привязки в лексический заключающей среде. Как правило, это будет функциональная среда непосредственно включающей функции.

    Даже если ArrowFunction может содержать ссылки на super, функциональный объект, созданный на шаге 4, не превращается в метод путем выполнения MakeMethod . ArrowFunction , что ссылки super всегда содержатся в не- ArrowFunction и необходимое состояние для реализации superдоступен через объем , который захватывается функция объект ArrowFunction .

  • Они не являются конструкторами.

    Это означает, что они не имеют внутреннего метода [[Construct]] и, следовательно, не могут быть созданы, например,

    var f = a => a;
    f(123);  // 123
    new f(); // TypeError: f is not a constructor
Ориоль
источник
8

Я прочитал, это символ Arrow FunctionsвES6

это

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

Использование Arrow Functionможет быть записано как

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

MDN Docs

Mritunjay
источник
6

Добавление простого примера CRUD с помощью функции Arrowfunction

 //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часть, и это большая тема. Это связано с тем, что thisозначает в JavaScript.

ВСЕ функции имеют неявный параметр с именем 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)

GMan
источник
2

Как уже говорилось во всех остальных ответах, это часть синтаксиса функции стрелки ES2015. Более конкретно, это не оператор, это punctuator маркер , который отделяет параметры от тела: ArrowFunction : ArrowParameters => ConciseBody. Например (params) => { /* body */ }.

JMM
источник
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. Теперь, поскольку 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 и в каких случаях контекст вызывающего не соблюдается.

Вы также можете увидеть демонстрацию функции Arrow с javascript в этом видео на YouTube, которое демонстрирует практически термин Context.

Шивпрасад Койрала
источник
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>

SlowLearner
источник