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