javascript — Являются ли «Функции стрелки» и «Функции» эквивалентными / взаимозаменяемыми?

«Функции стрелок» и «Функции» эквивалентны / взаимозаменяемы?

ДЛ: Нет! Функции стрелок и объявления / выражения функций не эквивалентны и не могут быть заменены вслепую.
Если функция, которую вы хотите заменить, не использует this , arguments и не вызывается с new , тогда да.


Как часто: это зависит . Функции со стрелками ведут себя иначе, чем объявления / выражения функций, поэтому давайте сначала посмотрим на различия:

1. Лексическая логика и arguments

Функции со стрелками не имеют своих привязок this или arguments . Вместо этого эти идентификаторы разрешаются в лексической области, как и любая другая переменная. Это означает, что внутри функции стрелки arguments this и arguments ссылаются на значения this и arguments в среде, в которой определена функция стрелки (т. Е. «Вне» функции стрелки):

 // 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: () ={amp}gt; console.log('Inside `bar`:', this.foo), }; } createObject.call({foo: 21}).bar(); // override `this` inside createObject 

В случае выражения функции this относится к объекту, который был создан внутри createObject . В случае функции стрелки this относится к самой функции createObject .

Это делает функции стрелок полезными, если вам нужен доступ к this из текущей среды:

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

Обратите внимание, что это также означает, что невозможно установить функцию стрелки с помощью .bind или .call .

Если вы не очень знакомы с this , подумайте о прочтении

2. Функции стрелок нельзя вызывать с new

ES2015 различает функции, которые могут вызываться, и функции, которые могут быть созданы. Если функция конструируемая, ее можно вызвать с помощью new , то есть new User() . Если функция вызывается, ее можно вызывать без new (т. Е. Обычного вызова функции).

Функции, созданные с помощью объявлений / выражений функций, могут быть как конструируемыми, так и вызываемыми.
Функции стрелок (и методы) могут быть вызваны только. конструкторы class являются только конструируемыми.

Если вы пытаетесь вызвать не вызываемую функцию или создать не конструируемую функцию, вы получите ошибку во время выполнения.


Зная это, мы можем утверждать следующее.

Сменная:

  • Функции, которые не используют this или arguments .
  • Функции, которые используются с .bind(this)

Не заменимо:

  • Функции конструктора
  • Функция / методы добавлены в прототип (потому что они обычно используют this )
  • Функции Variadic (если они используют arguments (см. Ниже))

Давайте посмотрим на это подробнее, используя ваши примеры:

Функция конструктора

Это не будет работать, потому что функции стрелок не могут быть вызваны с new . Продолжайте использовать объявление функции / выражение или использовать class .

Методы прототипа

Скорее всего, нет, потому что методы-прототипы обычно используют this для доступа к экземпляру. Если они не используют this , то вы можете заменить его. Однако, если вам важен краткий синтаксис, используйте class с кратким синтаксисом метода:

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

Методы объекта

Аналогично для методов в литерале объекта. Если метод хочет ссылаться на сам объект через this , продолжайте использовать выражения функции или используйте синтаксис нового метода:

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

Callbacks

По-разному. Вы должны определенно заменить его, если вы используете псевдоним внешнего или this .bind(this) :

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

Но: если код, который вызывает обратный вызов, явно устанавливает this конкретное значение, как это часто имеет место в обработчиках событий, особенно в jQuery, и обратный вызов использует this (или arguments ), вы не можете использовать функцию стрелки!

Вариадические функции

Так как функции стрелок не имеют своих собственных arguments , вы не можете просто заменить их функцией стрелок. Однако ES2015 представляет альтернативу использованию arguments : параметр rest .

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

Связанный вопрос:

Другие ресурсы:

Понравилась статья? Поделиться с друзьями:
JavaScript & TypeScript
Adblock
detector