ES5/ES6 Klasy

0

Czy metody "klasy" powinny zawsze znajdować się w ciele klasy? Chodzi mi o kod pisany w standardzie ES6, przykładowo:

class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
  }

  sleep() {
      return 'zzzzz';   
  }
}
const me = new Person('Me', 7);

Ostatnio widziałem gdzieś kod, który "w stary" sposób dodawał metodę Person.prototype.eat = function(food) {...} pomimo tego, że klasa była zdefiniowana jak powyżej. Wydało mi się to dziwne, że jest to tak napisane, bo o ile wszystko dobrze rozumiem, to pisząc klasę bez cukru z ES6 poprzez .prototype.xxx dodaję się metody, a przynajmniej powinno, bo wszystko co jest w var Person = function(name, age) {...} pełniło rolę konstruktora (metody w tej funkcji za każdym razem deklarowałyby się na nowo przy tworzeniu nowych ludzi?). W innym pliku było jeszcze coś na wzór:

class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
  }
}

{....}

Person.prototype = {
    eat: function(food) {
        return this.name + ' eats ' + food;
    },
    sleep: function() {
        return 'zzzzz'
    }
}
const me = new Person('Me', 7);

W tym przypadku kod w ogóle nie działał (a przynajmniej nie potrafiłem odtworzyć działającej uproszczonej wersji), na pierwszy rzut oka zwyczajnie metody eat i sleep były niedostępne dla me, dopiero tryb ścisły wyrzucił błąd, że nie można przypisać nic do prototypu klasy (jest tylko do odczytu). W standardzie ES5 można było w ten sposób dodać metody, ale chyba nie było to dobrą praktyką (nadpisanie prototypu?)

Wszystkie źródła jakie do tej pory przeczytałem w każdym przypadku sugerowały, aby metody definiować w ciele klasy ES6 class, jak w pierwszym przykładzie. Mógłby ktoś rozjaśnić nieco sytuację?

Co do przytoczonego kodu, to jeżeli będzie trzeba to postaram się znaleźć link do tego repo, całość wyglądała trochę na nieudaną próbę przepisania kodu do ES6, w ramach ćwiczeń próbowałem to jakoś zrozumieć/przeanalizować, może to jakiś pattern którego nie rozumiem i nie byłem w stanie wygooglować. W każdym razie będę wdzięczny za wszelkie wskazówki/wyjaśnienia.

0

Jeżeli używasz klas z ES6 to używaj, tyle.

2

Ostatnio widziałem gdzieś kod, który "w stary" sposób dodawał metody Person.prototype.eat = function(food)
pomimo tego, że klasa była zdefiniowana jak powyżej. Ten fragment kodu działał, ale wydało mi
się to dziwne, bo o ile wszystko dobrze rozumiem,

Nie ma w tym nic dziwnego - przecież klasy w ES6 są pod spodem zbudowane na prototypach (a same klasy to funkcje!). Inna sprawa, czy robienie klas ES6 i walenie potem Person.prototype.eat jest eleganckie czy nie (o ile ktoś nie miał ważnego powodu, to pewnie nie), ale to już są kwestie pozatechniczne.

Person.prototype = {
...
W tym przypadku kod w ogóle nie działał

Najpierw sam miałem zagwozdkę, jak to sprawdzałem teraz (bo na logikę niby powinien działać), ale okazuje się, że jak robisz coś na klasach, to ci blokuje przed zapisem właściwość prototype funkcji Person . Weź sobie napisz:

console.log(Object.getOwnPropertyDescriptor(Person, 'prototype'));

i zobacz, co się pojawi, że jest zablokowane przed zapisem (nie wiem natomiast czy wynika to ze specyfikacji czy z silnika V8, w którym sprawdzałem).

A, że można napisać Person.prototype.eat to inna sprawa - bo w ten sposób nie zmieniasz przecież właściwości prototype.

0
spartanPAGE napisał(a):

Jeżeli używasz klas z ES6 to używaj, tyle.

Chciałbym rozumieć zanim zacznę używać z czystym sumieniem :)

LukeJL napisał(a):

Ostatnio widziałem gdzieś kod, który "w stary" sposób dodawał metody Person.prototype.eat = function(food)
pomimo tego, że klasa była zdefiniowana jak powyżej. Ten fragment kodu działał, ale wydało mi
się to dziwne, bo o ile wszystko dobrze rozumiem,

Nie ma w tym nic dziwnego - przecież klasy w ES6 są pod spodem zbudowane na prototypach (a same klasy to funkcje!). Inna sprawa, czy robienie klas ES6 i walenie potem Person.prototype.eat jest eleganckie czy nie (o ile ktoś nie miał ważnego powodu, to pewnie nie), ale to już są kwestie pozatechniczne.

Person.prototype = {
...
W tym przypadku kod w ogóle nie działał

Najpierw sam miałem zagwozdkę, jak to sprawdzałem teraz (bo na logikę niby powinien działać), ale okazuje się, że jak robisz coś na klasach, to ci blokuje przed zapisem właściwość prototype funkcji Person . Weź sobie napisz:

console.log(Object.getOwnPropertyDescriptor(Person, 'prototype'));

i zobacz, co się pojawi, że jest zablokowane przed zapisem (nie wiem natomiast czy wynika to ze specyfikacji czy z silnika V8, w którym sprawdzałem).

A, że można napisać Person.prototype.eat to inna sprawa - bo w ten sposób nie zmieniasz przecież właściwości prototype.

Dziękuję Ci bardzo, wyjaśniłeś mój problem.

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0