оригинал:Рисовое путешествие avlutin.com/Мне очень-не-к…
Переводчик: Front-end Xiaozhi
Чем больше вы знаете, тем больше вы не знаете
Ставьте лайк и смотрите снова, формируйте привычку
эта статьяГитхаб:GitHub.com/QQ449245884…Он был включен в вышеизложенное, и более ранние статьи с высокими похвалами были классифицированы, а также было систематизировано множество моих документов и учебных материалов. Добро пожаловать в Star and Perfect. Вы можете обратиться в тестовый центр для ознакомления во время собеседования. Надеюсь, у нас что-то получится вместе.
Чтобы обеспечить удобочитаемость, в этой статье используется вольный перевод, а не дословный перевод.
За прошедшие годы ES6 вывел удобство использования JS на новый уровень: стрелочные функции, классы и многое другое — это здорово.
Функция стрелки — одна из самых ценных новых функций, есть много хороших статей, описывающих ее контекст и краткий синтаксис прозрачности.
Но у каждой сделки есть две стороны. Часто новые функции вносят некоторую путаницу, одна из которых заключается в том, что стрелочные функции неверны. В этой статье будут рассмотрены некоторые сценарии, в которых вы должны обойтистрелочная функциявместо этого используйте старые добрые функциональные выражения или новый сокращенный синтаксис. И будьте осторожны, чтобы сократить код, так как это влияет на читабельность кода.
1. Определите методы объекта
В JS методы — это функции, хранящиеся в свойствах объекта. При вызове этого методаthis
Укажет на объект, которому принадлежит метод.
Object literal
Из-за короткого синтаксиса стрелочной функции привлекательно использовать ее для определения методов, давайте попробуем:
const calculate = {
array: [1, 2, 3],
sum: () => {
console.log(this === window); // => true
return this.array.reduce((result, item) => result + item);
}
};
console.log(this === window); // => true
// Throws "TypeError: Cannot read property 'reduce' of undefined"
calculate.sum();
calculate.sum
Методы определяются с помощью стрелочных функций. Но при звонкеcalculate.sum()
броситTypeError
,потому чтоthis.array
дляundefined
.
при звонкеcalculate
методы на объектахsum()
, контекст по-прежнемуwindow
. Это происходит потому, что стрелочные функции лексически связывают контекст сwindow
объект.
воплощать в жизньthis.array
Эквивалентноwindow.array
,этоundefined
.
Обходной путь заключается в использовании регулярных функциональных выражений для определения методов. это определяется во время вызова, а не окружающим контекстом, вот фиксированная версия:
const calculate = {
array: [1, 2, 3],
sum() {
console.log(this === calculate); // => true
return this.array.reduce((result, item) => result + item);
}
};
calculate.sum(); // => 6
потому чтоsum
является обычной функцией, поэтому при вызовеcalculate.sum()
Времяthis
даcalculate
объект.this.array
является ссылкой на массив, поэтому сумма элементов вычисляется правильно:6
.
Object prototype
Те же правила применяются к определению методов объектов-прототипов. Используйте функцию стрелки, чтобы определитьsayCatName
метод,this
направлениеwindow
function MyCat(name) {
this.catName = name;
}
MyCat.prototype.sayCatName = () => {
console.log(this === window); // => true
return this.catName;
};
const cat = new MyCat('Mew');
cat.sayCatName(); // => undefined
Определяйте выражения функций ранее:
function MyCat(name) {
this.catName = name;
}
MyCat.prototype.sayCatName = function() {
console.log(this === cat); // => true
return this.catName;
};
const cat = new MyCat('Mew');
cat.sayCatName(); // => 'Mew'
sayCatName
Обычная функция при вызове в качестве метода меняет контекст наcat
Объект:cat.sayCatName()
.
2. Функция обратного вызова динамического контекста
this
В JS есть мощная функция, позволяющая изменять контекст в зависимости от того, как вызывается функция. Обычно контекст — это целевой объект, в котором происходит вызов, что делает код более естественным, чем то, что произошло с этим объектом.
Однако стрелочные функции статически привязывают контекст к объявлению и не могут сделать его динамическим, но в этом есть и хорошие, и плохие, иногда нужна динамическая привязка.
Присоединение прослушивателей событий к элементам DOM — обычная задача клиентского программирования. Событие запускает функцию обработчика иthis
В качестве целевого элемента он недостаточно гибок, чтобы использовать здесь стрелочные функции.
В следующем примере делается попытка использовать стрелочные функции для такого обработчика:
const button = document.getElementById('myButton');
button.addEventListener('click', () => {
console.log(this === window); // => true
this.innerHTML = 'Clicked button';
});
в глобальном контекстеthis
направлениеwindow
. Когда происходит событие щелчка, браузер пытается вызвать функцию-обработчик с контекстом кнопки, но функция стрелки не меняет свой предопределенный контекст.this.innerHTML
эквивалентноwindow.innerHTML
, бессмысленно.
Должно быть применено функциональное выражение, которое позволяет вносить изменения в зависимости от целевого элемента.this
:
const button = document.getElementById('myButton');
button.addEventListener('click', function() {
console.log(this === button); // => true
this.innerHTML = 'Clicked button';
});
Когда пользователь нажимает кнопку, в функции обработчикаthis
направлениеbutton
. Отсюда вопрос.innerHTML = 'Clicked button'
Правильно измените текст кнопки, чтобы он отражал состояние нажатия.
3. Вызвать конструктор
this
В вызове конструкции находится только что созданный объект. при исполненииnew MyFunction()
когда конструкторMyFunction
Контекст — это новый объект:this instanceof MyFunction === true
.
Уведомление, стрелочные функции нельзя использовать в качестве конструкторов. JavaScript неявно предотвращает это, генерируя исключения.
в любом случае,this
- это настройка из окружающего контекста, а не только что созданного объекта. Другими словами, вызовы конструктора стрелочных функций бессмысленны и неоднозначны.
Давайте посмотрим, что произойдет, если мы попытаемся сделать это:
const Message = (text) => {
this.text = text;
};
// Throws "TypeError: Message is not a constructor"
const helloMessage = new Message('Hello World!');
воплощать в жизньnew Message('Hello World!')
,вMessage
Является стрелочной функцией, JavaScript выдаетTypeError
ошибка,Message
Не может использоваться в качестве конструктора.
Приведенный выше пример можно исправить с помощью функционального выражения, что является правильным способом создания конструктора (включая объявление функции):
const Message = function(text) {
this.text = text;
};
const helloMessage = new Message('Hello World!');
сокращенный синтаксис
У стрелочных функций есть хорошее свойство опускать круглые скобки параметров.()
, Масса блока{}
, который возвращается, если тело функции содержит только один оператор. Это помогает писать очень короткие функции.
Профессор программирования в колледже автора дал студентам интересное задание: написать кратчайшую функцию для вычисления длины строки на языке C — отличный способ выучить и изучить новый язык.
Однако в реальных приложениях многие разработчики читают код. Самый короткий синтаксис не всегда подходит для того, чтобы помочь вашим коллегам сразу понять полезность метода.
В некотором смысле сокращенные функции становятся трудными для чтения, поэтому старайтесь не злоупотреблять ими. Давайте посмотрим на пример
const multiply = (a, b) => b === undefined ? b => a * b : a * b;
const double = multiply(2);
double(3); // => 6
multiply(2, 3); // => 6
multiply
Возвращает результат умножения двух чисел или замыкание, привязанное к первому аргументу, для будущих операций умножения.
Функция работает нормально и выглядит коротко. Но трудно понять, что он делает с самого начала.
Чтобы сделать его более читабельным, необязательные фигурные скобки иreturn
Заявление или используйте регулярную функцию:
function multiply(a, b) {
if (b === undefined) {
return function(b) {
return a * b;
}
}
return a * b;
}
const double = multiply(2);
double(3); // => 6
multiply(2, 3); // => 6
Хорошо найти баланс между краткостью и многословием, что делает код более интуитивным.
Суммировать
Без сомнения, стрелочные функции — отличное дополнение. При правильном использовании он заставляет переднюю часть использовать.bind()
Или там, где попытка захватить контекст становится простой, это также упрощает код.
Что хорошо в одних ситуациях, может быть плохо в других. Стрелочные функции нельзя использовать, когда требуется динамический контекст: определение методов, использование конструкторов для создания объектов, обработка событий изthis
Получите цель.
Ошибки, которые могут существовать после развертывания кода, не могут быть известны в режиме реального времени.Чтобы решить эти ошибки впоследствии, много времени тратится на отладку журнала.Кстати, я рекомендую всем полезный инструмент мониторинга ошибок.Fundebug.
Коммуникация (приглашаем вступить в группу, группа будет присылать красные конверты по рабочим дням, технология интерактивного обсуждения)
Статьи из серии галантерейных товаров резюмируются следующим образом: если вы чувствуете себя хорошо, нажмите «Звезда», добро пожаловать в группу, чтобы учиться друг у друга.
Я Сяо Чжи, автор официального аккаунта "Moving the World",Продолжайте знакомить энтузиастов с передовыми технологиями. Я буду часто делиться тем, что я узнал и увидел, На пути продвижения, давайте подбадривать друг друга!
Обратите внимание на публичный аккаунт и отвечайте в фоновом режимеБлагосостояние, вы можете увидеть преимущества, вы знаете.
Приложение: Новая статья будет отправлена в публичный аккаунт за сутки