Обсуждение было закрыто, потому что я перешел от DEV к блогу на своем личном сайте. Если вы хотите поболтать о содержании какой-либо статьи, напишите мне в Twitter.
Существует множество статей не только здесь, на DEV, но и по всему интернету о том, что такое this
в JavaScript. Это потому, что this
— одна из самых запутанных тем о JavaScript для новичков, даже если они имеют опыт работы с другими языками программирования.
Существует множество ответов на вопрос «Что такое this
?», но с моей точки зрения ответ только один: «Технический долг», и это потому, что для меня все, что написано с использованием this
, может и должно быть написано без него.
В этой статье мы рассмотрим некоторые причины, по которым вы, возможно, захотите избежать this
.
Неявное нехорошо
this
— это неявное значение, что означает, что вы не определяете его как аргумент ваших функций, как переменную или что-то подобное. Оно уже определено за вас. Вы можете подумать на секунду «это здорово», но вы должны учитывать, что в зависимости от того, где вы находитесь в вашем коде, this
меняется, поэтому вы не можете быть на 100% уверены в том, каково его текущее значение.
console.log(this); // Will log `globalThis`.
const object = {
shouldLogObject() {
console.log(this);
},
};
object.shouldLogObject(); // Will log `object`
[1, 2, 3].map(object.shouldLogObject); // Will log `globalThis` 3 times (???)
const aFunction = function () {
console.log(this);
};
aFunction(); // Will log `globalThis`
const arrowFunction = () => console.log(this); // Will log `globalThis`
aFunction.call("foo"); // Will log `"foo"`
Теперь давайте посмотрим, как это выглядит, если не использовать this
:
console.log("hello"); // Will log `"hello"`.
const object = {
shouldLogArgument(argument) {
console.log(argument);
},
};
object.shouldLogArgument("foo"); // Will log `"foo"`
[1, 2, 3].map(object.shouldLogArgument); // Will log `1`, `2` and `3`
const aFunction = function (argument) {
console.log(argument);
};
aFunction("foo"); // Will log `"foo"`
// Will log the value of `argument`:
const arrowFunction = argument => console.log(argument);
aFunction("foo"); // Will log `"foo"`
Это почти такой же объем кода, но теперь довольно ясно, что все делает, потому что мы говорим об этом прямо.
«Решения» еще хуже.
В некоторых сообщениях говорится, что «легко» решить подобную проблему, используя некоторые методы, которые поставляются вместе с функцией: bind
, call
и apply
. На мой взгляд, это все равно что ставить заплатки поверх заплаток вместо того, чтобы устранить корневую проблему. Допустим, у нас есть функция, которая принимает обратный вызов onEvent
:
// with plain functions:
onEvent(doSomething); // readable, no issues here
// but with class methods:
onEvent(instance.doSomething); // will break if it uses `this`
// to "solve" that:
onEvent(event => instance.doSomething(event)); // verbose
// or
onEvent(instance.doSomething.bind(instance)); // wth?!
// or when you write the class itself:
class Example {
constructor() {
this.doSomething = this.doSomething.bind(this); // 🤮
}
}
Если вы не используете классы…
У меня уже есть пост на DEV о том, почему вам не нужны классы для написания кода, и этот пост как бы связан с ним, в основном потому, что это
чрезвычайно часто встречается при работе с классом
. Вы можете сказать, что если вы работаете со статическими методами и тому подобным, то вы не используете this
, но тогда мой ответ на это таков: Зачем тогда вообще использовать class
? Вы могли бы просто сделать эти статические методы функциями в модуле и использовать их напрямую.
Так бесполезно ли изучать, что такое this
?
Нет, вам определенно нужно знать, как это работает, не говоря уже о том, что существует множество нативных API в браузере и на сервере, которые используют классы, и знание того, как обращаться с this
, полезно при работе с ними. Я хочу сказать, что вы должны избегать кода, использующего this
, чтобы сделать свою жизнь и жизнь других разработчиков лучше.
Заключительные мысли
Я написал эту статью в основном потому, что некоторые люди, которые объясняют, что такое this
, также пытаются «продать его» как что-то хорошее, когда на самом деле это отстой, так что идите и узнайте, как с ним справиться, если вы встретите this
в природе, но избегайте его как можно больше в коде, автором которого вы являетесь.
Вот и все. Вот и весь пост.
Если вы согласны, я буду рад прочитать сценарии, в которых this
испортил вам жизнь, а если вы не согласны, пожалуйста, прокомментируйте причины, по которым вы считаете хорошей идеей полагаться на неявное значение вроде this
.
Спасибо, что уделили время чтению!
Будьте здоровы!