С 2015 года JavaScript значительно улучшился.

Пользоваться им сейчас гораздо приятнее, чем когда-либо.

В этой статье мы рассмотрим имена функций и стрелочные функции в JavaScript.

Определите, была ли функция вызвана через new

Мы можем узнать, была ли функция вызвана с помощью new, используя свойство new.target.

Например, мы можем написать следующее, чтобы остановить вызов функции с new :

function foo() {
  if (new.target !== undefined) {
    throw new Error('cannot be called as constructor');
  }
  //...
}

Если мы вызовем его с new foo() , мы получим ошибку «Неперехваченная ошибка: не может быть вызвана как конструктор».

С ES5 мы можем проверить значение this :

function foo() {
  "use strict";
  if (this !== undefined) {
    throw new Error('cannot be called as constructor');
  }
  //...
}

Если this является undefined в строгом режиме, то мы знаем, что он не вызывается с new.

Стрелочные функции

Стрелочные функции — это новые виды функций, представленные в ES6.

Решает проблему привязок с this , arguments и другими встроенными объектами.

Кроме того, их нельзя использовать в качестве конструкторов, и они короче.

Это означает, что они отлично подходят для обратных вызовов.

Традиционные функции — плохие функции без методов

Традиционные функции — это плохие функции, не являющиеся методами, поскольку они связываются со своим собственным значением this внутри функции.

Поэтому следующий пример не будет работать:

function Suffix(suffix) {
  this.suffix = suffix;
}
Suffix.prototype.addSuffix = function(arr) {
  'use strict';
  return arr.map(function(x) {
    return x + this.suffix;
  });
};

Обратный вызов определяется традиционной функцией, поэтому он имеет собственное значение this.

Поэтому в обратном вызове нет свойства suffix.

Чтобы исправить это, мы можем присвоить this снаружи другое значение.

Например, мы можем написать:

function Suffix(suffix) {
  this.suffix = suffix;
}
Suffix.prototype.addSuffix = function(arr) {
  'use strict';
  var that = this;
  return arr.map(function(x) {
    return x + that.suffix;
  });
};

Мы назначили this вне обратного вызова на that, чтобы мы могли использовать его в обратном вызове.

Мы также можем указать значение this с помощью метода map.

Значение передается во 2-й аргумент:

function Suffix(suffix) {
  this.suffix = suffix;
}
Suffix.prototype.addSuffix = function(arr) {
  'use strict';  
  return arr.map(function(x) {
    return x + this.suffix;
  }, this);
};

Мы передаем this во 2-й аргумент, чтобы установить this в обратном вызове конструктора Suffix.

И мы также можем использовать bind(this) для возврата новой функции с нужным нам значением this:

function Suffix(suffix) {
  this.suffix = suffix;
}
Suffix.prototype.addSuffix = function(arr) {
  'use strict';  
  return arr.map(function(x) {
    return x + this.suffix;
  }.bind(this));
};

С ES6 нам не нужно ничего этого делать.

Мы просто используем стрелочные функции:

function Suffix(suffix) {
  this.suffix = suffix;
}
Suffix.prototype.addSuffix = function(arr) {
  return arr.map((x) => {
    return x + this.suffix;
  });
};

Мы заменяем нашу функцию функцией стрелки, поэтому нам не нужно беспокоиться о значении this в обратном вызове.

Мы можем заменить конструктор синтаксисом класса:

class Suffix {
  constructor(suffix) {
    this.suffix = suffix;
  }
  addSuffix(arr) {
    return arr.map((x) => {
      return x + this.suffix;
    });
  }
}

Мы размещаем все внутри класса.

Вывод

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

Кроме того, стрелочные функции не привязываются к каким-либо специальным значениям, таким как this внутри, поэтому мы можем легко использовать их для обратных вызовов.