2016-12-13 99 views
5

lubię zajęcia ES6 ale nie mogę zrozumieć, dlaczego muszę związać metody w konstruktorów tak:Dlaczego metody ESP nie są metodami obiektu utworzonego przy użyciu klasy powiązanej z tą klasą?

constructor() { 
    this.someMethod = this.someMethod.bind(this) 
} 

muszę zrobić, to prawie na każdej metody.

Czy to jest prawdziwe ograniczenie, czy też czegoś brakuje? Jaki jest tego powód? Wiem, że klasy w JS są tylko cukrem syntaktycznym, ale to mogło być częścią nich.

+0

to dlatego, że przekazujesz funkcje innym funkcjom, które zmieniają kontekst. takie jak programy obsługi zdarzeń. Funkcje strzałek ułatwiają obsługę: 'foo.on ('kupa', e => this.someMethod (e))' –

+4

https://esdiscuss.org/topic/why-are-es6-class-methods- nie-automatycznie-związany-do-instancji – Gerrit0

+0

to z powodu tego, jak "to" działa w JS (-functions), i nie ma nic wspólnego z klasami w szczególności. I to jest również powód/sposób, w jaki prototypowe dziedziczenie działa w JS. JS nie jest tak sztywny jak Java. Może używasz niewłaściwego konstruktu? Może jest lepsze podejście? – Thomas

Odpowiedz

4

Cytując odpowiedź Mark Miller do the linked esdiscuss post tutaj:

Kilka pierwszych propozycji klasy zrobił tak, jak zostały one począwszy od semantyki obiektów-as-zamknięć ES5 i klas jak kompozycje-of-instance- cechy.

doku.php?do=search&id=traits

Chodziło o to, że obsługa języka byłoby to semantyka efektywne, unikając konieczności chętnie przeznaczyć zamknięcie danej metody na przykład.

Jednak z powodów, które rozumiem, te nie zyskały przyczepności. Zamiast tego, poruszamy się w kierunku cukru, aby dominujący wzorzec kodowania es5 przekształcił się w dziedziczenie prototypowe. Początkowo staraliśmy się, aby był to wyłącznie cukier, tak aby ludzie mogli bezboleśnie przekształcać kod w tym dominującym wzorze w klasy.

Gdy zmagaliśmy się ze szczegółową semantyką wokół super i konstrukcji, klasy es6 odbiegały od czystego cukru. Ale to odchylenie tylko zapobiega bezbolesnemu refaktoryzacji z klas es6 do dominującego wzorca es5. Praktycznie nie ma problemu z refakturowaniem wzorca es5 do klas es6.

Na zenparsing/es-function-bind#17 zrozumieliśmy

mogliśmy nadal mieli metody wiązania na wydobycie - rozliczanie za zachowanie przez decreeing że metody są instalowane na prototypie jako dostępowych których getter wiąże. Jednak ta realizacja nastąpiła zbyt późno dla es6. Ponieważ uczyniłoby to refaktoryzację klasami bardziej niebezpiecznymi - bardziej semantyczną - nie jest jasne, czy poleciałby, nawet gdybyśmy pomyśleli o tym na czas. Zamiast tego, pod wszystkimi wariantami projektów dekoratorów, można napisać takiego dekoratora tak, aby udekorowane metody były bind-on-extraction, przez jawne tworzenie tej właściwości accessora. Jednak (!), Jeśli zostanie zaimplementowany jako dekorator terenu użytkownika, ma on znacznie gorszą wydajność niż obiekty-jako-zamknięcia !! Obiekty-jako-zamknięcia mają wyższy koszt alokacji przy przydzielaniu obiektu.

jsperf.com/creating-stateful-objects

Ale są bardzo wydajne przy użyciu obiektu po utworzeniu obiektu.

jsperf.com/strict-where-state

(Zauważ, że jsperf jest Błędna ocena typów krawędzi 28.14257.1000.0 jak Chrome 46.0.2486 Jest Warto zauważyć, ponieważ Edge korzysta z transponowanej reprezentacji dla Słabych Map, a więc korzystanie z prywatnego stanu WeakMap ma znacznie mniejszą karę na Edge.)

Aby dekorator dla efektywnego wiązania był efektywny, implementacja musiałaby mieć gdzieś specjalny przypadek, aby uniknąć alokacji, gdy metoda jest natychmiast wywoływana, a nie jest uzyskiwana w sposób możliwy do wyodrębnienia.Jedyną rzeczą, którą TC39 musi zrobić, aby to umożliwić, jest standaryzacja takiego dekoratora, tak aby implementacje mogły zapewnić go jako wbudowany, który rozpoznaje.

i Kevina Smitha odpowiedź:

W ogóle, często istnieje napięcie między dokonywania język „lepiej” (dla pewnego systemu wartości subiektywnej) i utrzymanie spójności. Myślę, że utrzymanie spójności było właściwym wezwaniem w tej sprawie.


Powiedział, że public class fieldsproposal pozwoli na zdefiniowanie metod instancji jako

class Foo { 
    someMethod =() => { 
    // do stuff 
    } 
} 

(zamiast robić to samo w constructor).

+0

@Bergi: Oczywiście. Ale jest to cukier syntaktyczny dla tego przypadku użycia. –

+0

Czy powinniśmy zamykać takie rzeczy jak [Dlaczego odwołanie do metody nie śledzi tego?] (Http://stackoverflow.com/q/35050878/1048572) jako dupe tego? Przysięgam też, że musi istnieć pytanie o to, dlaczego metody prototypów ES5 nie wiążą się z ekstrakcją, co może być cenne w łączeniu, ale nie mogę go znaleźć. – Bergi

+0

Czy ktoś może wznowić bardziej praktycznie to, co powiedział Mark Miller? – marco