@Boris009

Что происходит со свойством класса при присвоении извне?

Что происходит со свойством, когда добавляем его к классу?
Почему оно не доступно в экземпляре?

class Str {
   text = 'hello'
}

Str.word = 'word'

const s = new Str()

console.log(s.text)
console.log(s.word)
  • Вопрос задан
  • 98 просмотров
Решения вопроса 4
@mvv-rus
Настоящий админ AD и ненастоящий программист
class - это функция. Которая выполняет роль конструктора класса при вызове через new. Если вы добавите к функции свойство, то у функции это свойство останется. А вот в созданный ей объект оно просто так не попадает. И не унаследуется - потому что в ссылку на протоип ([[Prototype]] и т.д.) созданного объекта операция new записывает содержимое свойства prototype функции-конструктора. Хотите добавить свойство в экземпляры class SomeClass - добавляте его в SomeClass.prototype. Или же добирайтесь через свойство constructor объекта-экземпляра (constructor.word) - вот оно указывает на функцию-конструктор.
Ответ написан
Комментировать
sergiks
@sergiks Куратор тега JavaScript
♬♬
Вы почувствовали разницу между «статическими» свойствами/методами и просто свойствами/методами.

Статические – принадлежат самому классу, но не его экземплярам.
Ответ написан
Комментировать
VoidVolker
@VoidVolker Куратор тега JavaScript
Dark side eye. А у нас печеньки! А у вас?
Str.word = 'word'
Добавили свойство word объекту Str.
const s = new Str()
Создали новый объект s с помощью вызова конструктора класса Str. Str и s - это два разных объекта. Str - объект типа класс, а s - это экземпляр класса. Список свойств экземпляра класса и его методы хранятся в отдельном объекте под названием "прототип", а не в самом объекте класса.
Рекомендую изучить механизмы работы прототипного наследования в мире JS и как работают конструкторы и классы: JavaScript-Garden -> constructors, JavaScript-Garden -> object.prototype
Ответ написан
Комментировать
Потому что если танцевать с js, то танцевать как надо:

Str.prototype.word = 'word'

А вообще

interface StrInterface {
    text: string
    word: string
}

class Str implements StrInterface {
    text = 'hello'
    word: string = ''
}
 
Str.prototype.word = 'word'
 
const s = new Str()
 
console.log(s.text)
console.log(s.word)



upd: Ситуативно через prototype - да, ты можешь "расширять" классы, но для таких ситуаций придуман "extends", который позволяет тебе расширять класс с дополнительными свойствами. И это будет правильно, потому что присвоение свойств напрямую, либо через тот же prototype - может происходить хаотично, например:

setInterval(() => {
    ++count
    Str.prototype.word = count % 2 == 0 ? 'word' : 'not word'
}, 1000)

Str.prototype.word = 'word'


И это сработает.

Сделано это из-за GC (garbagecollector).

И такое хаотичное присвоение свойств (чего-либо) считается плохой практикой. Точно так же со стрелочными функциями, которые создаются заново каждый раз и так-же могут упираться в какую-то кондицию, которая каждое исполнение скрипта может их выполнять в разных вариациях (попробуй экспортировать: export default () => { ... }). Точно так-же - все импорты - иммутабельны. Даже если ты экспортируешь так: export let value = 'word', то при импорте в другой модуль - ты этот value не изменишь, никак.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы