ES5/ES6 Klasy

LE
  • Rejestracja:ponad 7 lat
  • Ostatnio:ponad 7 lat
  • Postów:7
0

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

Kopiuj
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:

Kopiuj
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.

edytowany 6x, ostatnio: let
spartanPAGE
  • Rejestracja:około 12 lat
  • Ostatnio:8 dni
0

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

LukeJL
Z jednej strony racja (nie ma co mieszać bez powodu, bo się kasza robi), z drugiej strony jednak warto wiedzieć, jak to działa pod spodem.
LukeJL
  • Rejestracja:około 11 lat
  • Ostatnio:9 minut
  • Postów:8423
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:

Kopiuj
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.


LE
  • Rejestracja:ponad 7 lat
  • Ostatnio:ponad 7 lat
  • Postów:7
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:

Kopiuj
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.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.