С 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
внутри, поэтому мы можем легко использовать их для обратных вызовов.