Какво е значението на =› (стрелка, образувана от равно и по-голямо) в JavaScript?

Знам, че операторът >= означава повече или равно на, но съм виждал => в някакъв изходен код. Какъв е смисълът на този оператор?

Ето кода:

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

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

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

person rpgs_player    schedule 23.07.2014    source източник
comment
Вижте тази връзка за функциите със стрелки.   -  person Mistalis    schedule 23.12.2016


Отговори (14)


Какво е

Това е функция със стрелка. Функциите със стрелка са кратък синтаксис, въведен от ECMAscript 6, който може да се използва подобно на начина, по който бихте използвали функционални изрази. С други думи, можете често да ги използвате вместо изрази като function (foo) {...}. Но те имат някои важни разлики. Например, те не обвързват собствените си стойности на this (вижте по-долу за обсъждане).

Функциите със стрелки са част от спецификацията на ECMAscript 6. Те все още не се поддържат във всички браузъри, но се поддържат частично или напълно в Node v. 4.0+ и в повечето модерни браузъри, използвани от 2018 г. (Включих частичен списък с поддържащи браузъри по-долу).

Можете да прочетете повече в документацията на Mozilla върху функциите със стрелки.

От документацията на Mozilla:

Израз на функция със стрелка (известен също като функция на дебела стрелка) има по-кратък синтаксис в сравнение с функционални изрази и лексикално обвързва this стойност (не обвързва своя собствена this, arguments, super или 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, но поддръжката на браузъра е на петна.

Поддръжката на браузъра за тази функционалност се подобри доста, но все още не е достатъчно разпространена за повечето приложения, базирани на браузър. От 12 декември 2017 г. се поддържа в текущите версии на:

  • Chrome (в. 45+)
  • Firefox (v. 22+)
  • Edge (в. 12+)
  • Opera (v. 32+)
  • Браузър за Android (в. 47+)
  • Opera Mobile (в. 33+)
  • Chrome за Android (в. 47+)
  • Firefox за Android (в. 44+)
  • Safari (в. 10+)
  • iOS Safari (в. 10.2+)
  • Интернет на Samsung (v. 5+)
  • Браузър Baidu (v. 7.12+)

Не се поддържа в:

  • IE (до ст. 11)
  • Opera Mini (до v. 8.0)
  • Браузър Blackberry (до v. 10)
  • IE Mobile (до v. 11)
  • UC Browser за Android (до v. 11.4)
  • QQ (до v. 1.2)

Можете да намерите повече (и по-актуална) информация на CanIUse.com (без партньорство).

person elixenide    schedule 23.07.2014
comment
TypeScript също изглежда го поддържа. - person mtyson; 01.05.2017
comment
Изглежда, че това е ламбда израз, нали? - person Addem; 31.08.2018
comment
Искам да спомена по отношение на съвместимостта на браузъра, че използвам функции със стрелки ES6/ES7 и други функции, които не са съвместими с IE11, но използвам Gulp или Webpack заедно с Babel, за да транспилирам ES6 в ES5, така че да работи в IE11. Така че, ако имате нужда от поддръжка на IE11 и нямате нищо против да настроите Babel, тогава се възползвайте. - person mbokil; 04.11.2019

Това е известно като функция със стрелка, част от 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
Още за синтаксиса

За повече, ето един доста добър отговор за < em>кога да използвате функции със стрелки.

person brbcoding    schedule 23.07.2014
comment
Би било добре да актуализирате демонстрациите, за да използвате esfiddle.net като es6fiddle.net вече не работи - person Wavesailor; 16.10.2018

Това са функции със стрелки

Известен също като Функции с дебели стрелки. Те са чист и сбит начин за писане на функционални изрази, напр. 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]

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

person Toby Mellor    schedule 26.04.2017

Това ще бъде „изразът на функцията стрелка“, въведен в ECMAScript 6.

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

За исторически цели (ако уики страницата се промени по-късно), това е:

Функционалният израз със стрелка има по-кратък синтаксис в сравнение с функционалните изрази и лексикално обвързва тази стойност. Функциите със стрелки винаги са анонимни.

person Kyle Falconer    schedule 23.07.2014
comment
имате ли предвид да включите достатъчно информация, така че повечето читатели да не се налага да се задълбочават? - person djechlin; 23.07.2014
comment
Уикито, към което се свързах, много накратко описва какво представлява: Функционален израз със стрелка има по-кратък синтаксис в сравнение с функционалните изрази и лексикално обвързва тази стойност. Функциите със стрелки винаги са анонимни. - person Kyle Falconer; 23.07.2014
comment
Добавянето на това като цитат тук наистина ще помогне на вашия отговор. - person Hanky Panky; 23.07.2014

само за да добавя още един пример за това какво може да направи ламбда без да използва 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
person Bart Calixto    schedule 23.07.2014

@user3227114 Без етикети на оста x не можете да видите ъгъла от графиката. Имайте предвид, че можете да промените височината и ширината на графиката и ъгълът може да изглежда различен, въпреки че винаги е един и същ.
person Oriol    schedule 11.10.2015

Четох, това е символ на Arrow Functions в ES6

това

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

използване на Arrow Function може да бъде написано като

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

MDN документи

person Mritunjay    schedule 23.07.2014

Недоволен от другите отговори. Най-гласуваният отговор към 2013/3/13 е фактически грешен.

Кратката лаконична версия на това, което означава =>, е, че това е пряк път за писане на функция AND за обвързването й към текущия 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(functionToBind, valueToUseForThis) {
  return function(...args) {
    functionToBind.call(valueToUseForThis, ...args);
  };
}

В по-стария JavaScript без оператора за разпространение би било

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

Разбирането на този код изисква разбиране на затварянията, но кратката версия е bind прави нова функция, която винаги извиква оригиналната функция със стойността this, която е била обвързана с нея. Функциите със стрелки правят същото, тъй като те са пряк път за bind(this)

person gman    schedule 13.03.2019

Добавяне на прост 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)); 
person Hitesh Sahu    schedule 02.11.2017

Функциите със стрелки, които са обозначени със символ (=>), ви помагат да създавате анонимни функции и методи. Това води до по-кратък синтаксис. Например, по-долу е проста функция „Добавяне“, която връща събиране на две числа.

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

Горната функция става по-кратка чрез използване на синтаксис „стрелка“, както е показано по-долу.

въведете описание на изображението тук

Горният код има две части, както е показано на горната диаграма: -

Вход: — Този раздел определя входните параметри за анонимната функция.

Логика: — Този раздел идва след символа „=>“. Този раздел има логиката на действителната функция.

Много разработчици смятат, че функцията със стрелка прави вашия синтаксис по-кратък, по-опростен и по този начин прави кода ви четим.

Ако вярвате на горното изречение, позволете ми да ви уверя, че това е мит. Ако си помислите за момент, че правилно написана функция с име е много по-четима от загадъчните функции, създадени в един ред с помощта на символ със стрелка.

Основната употреба на функцията стрелка е да гарантира, че кодът се изпълнява в контекста на извикващия.

Вижте кода по-долу, в който има дефинирана глобална променлива „context“, тази глобална променлива е достъпна вътре във функция „SomeOtherMethod“, която се извиква от друг метод „SomeMethod“.

Този "SomeMethod" има локална променлива "контекст". Сега, тъй като „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 и в кои сценарии контекстът на повикващия не се зачита.

Можете също така да видите демонстрацията на функция стрелка с javascript в този видеоклип в YouTube, който демонстрира на практика термина Контекст.

person Shivprasad Koirala    schedule 10.02.2019

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

person JMM    schedule 30.09.2015

Както казаха други, обикновените (традиционни) функции използват 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>

person SlowLearner    schedule 17.09.2019

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

person Willem van der Veen    schedule 29.08.2018

Функциите със стрелки на JavaScript са приблизително еквивалентни на ламбда функции в python или блокове в Ruby. Това са анонимни функции със собствен специален синтаксис и работят в контекста на обхващащия обхват. Това означава, че те нямат собствено това, а вместо това имат достъп до това от функцията за непосредствено обхващане.

От ECMA стандарт:

ArrowFunction не дефинира локални обвързвания за аргументи, super, this или new.target. Всяка препратка към аргументи, super, this или new.target в рамките на ArrowFunction трябва да се преобразува в обвързване в лексикално обхващаща среда. Обикновено това ще бъде функционалната среда на непосредствено обхващаща функция.

Често можете да прочетете, че изразът на функция със стрелка е компактна алтернатива на традиционен израз на функция, това не е правилно. Функцията стрелка НЕ ​​е съкращение за традиционна функция, те се държат различно от традиционната функция.

Синтаксис

// 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;
person gagarine    schedule 22.07.2021
comment
Нито една функция в JS няма фиксиран брой аргументи - person Bergi; 22.07.2021
comment
@Bergi да, прав си. Исках да кажа синтаксис за приемане на аргумент, но това беше подвеждащо. Мисля, че вече е ясно с кодовия фрагмент. - person gagarine; 22.07.2021
comment
Между другото, те също имат свой собствен (променлив) обхват. Те нямат отделна стойност this, която често се нарича контекст. - person Bergi; 22.07.2021
comment
@Bergi коригира обхвата - person gagarine; 23.07.2021