Что такое `это`? Технический долг!


Обсуждение было закрыто, потому что я перешел от 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.

Спасибо, что уделили время чтению!

Будьте здоровы!

Оцените статью
Procodings.ru
Добавить комментарий