Комментарии 40
В старые времена мы делали var that = this
. Нам уже ничего не страшно
Пост странный, это же банальная область видимости и перекрытие (поправьте, если не так). Гораздо более интересно, зачем использовать this в тех, местах, где есть только одна переменная класса и никакого перекрытия нет. Вот этот вопрос меня до сих пор мучает.
ПС Я пишу бэк, но было пару пет проектов на js / ts.
Да, это действительно банальное перекрытие области видимости, но для новичков даже оно иногда выглядит как магия. А что для вас казалось необъяснимым чудом в коде?
Смею предположить, что каждого своя боль и магия на старте)))))
Боже, какое банальное перекрытие области видимости? Причем тут вообще область видимости?
const Y = f => ( h => h(h) ) ( g => f( x => g(g)(x) ) ); https://ru.wikipedia.org/wiki/Комбинатор_неподвижной_точки
При чем тут перекрытие?
function f1(id: string) {
const f2 = (id: number) => {}
}
Вот перекрытие.
Потому что в js нет неявного обращения к this, если я правильно вас понял.
Так же как и в c++, когда в конструкторе класса указываешь age = _age, а перед этим int age; вне конструктора,
да и зачем в функции использовать this, когда уже давно используются классы?
class Person {
contructor(age, name) {
this.name = name;
this.age = age;
}
}
но можно пойти дальше!
constructor(obj) {
for (const key of Object.keys(obj))
this[key] = obj[key];
}
и тогда new Person({
name: 'test',
age: 5
});
будет сразу получать свойства без лишних this[var] = value;
Согласна, решение с передачей объекта в конструктор выглядит гораздо элегантнее и убирает всю эту рутину с this[var] = value
. Прямо минимализм, который и читать приятнее, и писать быстрее.
Подход с передачей объекта в конструктор и автоматическим присваиванием свойств выглядит лаконично. Часто ли используете его на практике? Есть ли подводные камни?
Я у себя использую вот такое:
export default class Fl64_Gpt_User_Back_Mod_Auth {
constructor(
{
Fl64_Gpt_User_Back_Defaults$: DEF,
TeqFw_Core_Back_Config$: config,
TeqFw_Core_Shared_Api_Logger$$: logger,
Fl64_Gpt_User_Back_Mod_User$: modUser,
Fl64_Gpt_User_Back_Mod_Token$: modToken,
'Fl64_Gpt_User_Shared_Enum_User_Status.default': STATUS,
}
) {
this.isValidRequest = async function (req) {...};
this.loadUser = async function ({trx, pin, passPhrase}) {...};
}
}
Все зависимости используются "по месту", прямо из конструктора. Ничего переприсваивать не надо. Периодически находятся индивиды, которые говорят, что так делать некошерно. Ну, у меня в приложении объекты, как правило, синглтоны, да и стиль близок к функциональщине - мне норм. Но для обычного ООП такое, конечно, диковато.
за именование - медаль.
Вы конечно можете смеяться, но... с такими именами очень удобно программировать с LLM :) Они сразу втыкают, о чём речь (в отличие от "кожанных мешков"). К тому же это просто калька с java'вского package
и с PHP'шного namespace
, адаптированная под текущие реалии JS. Примерно такой же подход использовался в PHP <5.3. Ищите "PHP Zend 1 namespaces".
Я использую разные решения, то что написал - лишь один из способов, но если свойств меньше 3-5, то мне проще this.var = var писать,
Вообще можно даже не циклом, а просто сделать у класса свойство params и в него добавлять объект со свойствами и потом их вызывать obj.params.var, вроде как тоже имеет место быть
Вот еще в интернете нашел интересный способ:class Person {
name;
age;
constructor(properties) {
Object.assign(this, properties);
}
}
for (const key of Object.keys(obj))
this[key] = obj[key];
}
Object.assign(this, obj);
Давно не писал на javascript, на C# решаем проблему соглашениями по именованию. Т е чтобы не писать this.name = name
пишем, например, _name = name
или Name = name
. Вообще, для меня использование this
- плохой тон, почти всегда (вообще всегда, кроме пары синтетических примеров) можно обойтись без него. В C# конечно.
Не понимаю. Вроде же понятно все и явно, идет присваивание параметров, атрибутам класса. На Java давно так пишу и вижу, что другие пишут. По мне так так лучше, чем именовать атрибуты класса mName = name или еще круче mName = pName. С this человек со стороны, не зная местных правил именований сразу разберется, что к чему. А вот что значит "_name = name" , вот тут как раз я бы подвис. Опять же нет необходимости выдумывать разные имена для параметров и атрибутов класса. Чем однообразнее, согласованее названия, тем кмк проще потом разбирать код, искать в нем.
Да все понятно и очень явно :) Тут, конечно, дело вкуса, а о вкусах не спорят. Я не предлагаю называть филды mName или pName - все это точно такой же camelCase. Всё же, мои соображения таковы:
Параметры метода - camelCase. Как и локальные переменные (обычно). У нас не какой-то супер-кастомный code style, +- все так делают (это пусть будет аксиома)
Вот смотришь на ревью, добавлена строчка
name = 1
. Будем считать, что присваивать значения input параметрам метода - плохая практика. Это локальная переменная, или человек забыл написатьthis
? А если есть и локальная переменная с таким именем, и филд - как понять? А если написано_name = 1
- всё сразу ясно и понятно.В принципе и так всегда должно быть понятно, что ты хочешь сделать. Код, который не требует комментариев, все дела. Если необходимо уточнять свои намерения, добавляя
this
- код уже ну типа не очень ясный. Если это не нужно - то иthis
не нужен.Отдельный смак - это проперти. Будем считать, что проперти пишутся в PascalCase (в C# +- все так делают, не знаю, есть ли проперти в Java). Писать
this.Name = 1
- чтобы что? Неужели где-то в глобальной области видимости естьName
который можно присвоить?А вызовы методов?
this.Method()
- как и в прошлом пункте, шанс того, что тут можно что-то перепутать, крайне невелик.
Таким образом, в зависимости от вкуса, модификатор может быть нужен только для филдов, и то, если не хватило мотивации называть их как-то по-другому. Во всех остальных случаях - не нужен никогда. А для одного частного случая, можно чуть заморочиться, и облегчить всем жизнь. Моё такое мнение.
Насчет человека со стороны. У нас люди не так часто меняются, но все же, когда это происходит - есть .editorconfig, stylecop и набор анализаторов, так что проблем с тем, чтобы вникнуть, не возникает. Даже без этого, если человек на основе одного-двух файлов не может понять, что к чему - может лучше с ним и не работать вообще.
А вот так написать религия не позволяет?
class Person {
constructor (
public name,
public age,
public anyProperty
) {}
}
Только это уже тайпскрипт
это не typescript, а javascript
Это именно typescript, потому что в js нет сахарного синтаксиса parameter properties, превращающего аргументы конструктора в свойства класса при использовании модификаторов public, private, protected и readonly. Собственно, интерпретатор js выдаст ошибку о некорректном синтаксисе.
Наверное, проблема была в том, что знак = читался как "равно". А нужно было читать как "присваивается значение".
Это еще что, я как-то подрабатывал помощником преподавателя, так ко мне на консультацию пришел однажды чел, взрослый, лет 35, который не понимал, что такое переменная и как она работает.
А моя личная боль на первых порах была в том, что никак не мог въехать в "возвращаемое значение". Хорошо помню как это раздражало в очередном тьюториале - "кто возвращает", "куда" и главное "зачем". Сейчас конечно смешно, но тогда это выглядело не то, что "магия", а какой-то мировой заговор преподавателей, которые твердят одно и то же, но не хотят объяснить толком что это такое.
У меня так с "регистром" в процессорах было - что значит "именованная ячейка памяти", зачем её именовать и почему просто не дать цифровой адрес, как всем остальным ячейкам памяти? Пока сам не стал использовать (не понимая!) в программах, так и морщил мозг, что это за фигня такая. С тех пор даже не напрягаюсь, если использую что-то, не понимая, как оно там внури всё устроено. Придёт время - пойму, а не пойму - значит и не надо было.
Я помню вначале пути путался с рекурсиями. Тогда для меня они выглядели, как магия.
Или может было что-то иное?
Меня ментально напрягли массивы в js, особенно массивы с "дырками". Странные на фоне массивов в других языках, где они являются непрерывным куском памяти. Сейчас отношусь к ним философски, но долгое время было не совсем понятно, с чем имею дело)
Не использую this в JS, чувствую себя отлично.
Это автор ещё C# не видел, где в последнее время принято this вообще не писать, из-за чего можно вполне увидеть подобные строчки:
Name = name;
Name: name,
Связано это с тем, что у C# довольно чёткие требования к кодстайлу и стиль наименования переменных, полей и свойств говорит о их области видимости.
Но если честно это по своему удобно.
Если честно, вообще не понимаю чьей либо боли относительно this... Пишешь код без использования this. Если в библиотеке - читаешь документацию. Если в современном js - есть классы и там всегда this = инстанс класса. Стрелочная функция = this родительской функции либо его отсутствие... И на худой конец ты сам можешь задать this через условный байнд - на моей практике потребовалось лишь пару раз....
может было что-то иное?
Когда я только начинал в свой путь в JavaScript и поборол эту тему с присвоением параметров через this
, я, вдруг, обнаружил, что у этого ключевого слова есть контекст выполнения...
Моя боль в JavaScript: когда this и переменные становятся головоломкой