Jaki jest standardowy sposób wywoływania metod statycznych? Mogę myśleć o użyciu constructor
lub używaniu samej nazwy klasy, nie podoba mi się ta druga, ponieważ nie wydaje mi się to konieczne. Czy ten pierwszy jest zalecanym sposobem, czy jest coś innego?
Oto (wymyślony) przykład:
class SomeObject {
constructor(n){
this.n = n;
}
static print(n){
console.log(n);
}
printN(){
this.constructor.print(this.n);
}
}
javascript
class
static
ecmascript-6
es6-class
simonzack
źródło
źródło
SomeObject.print
czuje się naturalnie. Alethis.n
wnętrze nie ma sensu, ponieważ nie ma instancji, jeśli mówimy o metodach statycznych.printN
nie jest jednak statyczne.Odpowiedzi:
Oba sposoby są opłacalne, ale robią różne rzeczy, jeśli chodzi o dziedziczenie z zastąpioną metodą statyczną. Wybierz tego, którego zachowania oczekujesz:
Odwoływanie się do właściwości statycznej za pośrednictwem klasy będzie w rzeczywistości statyczne i stale będzie dawać tę samą wartość. Za pomocą
this.constructor
zamiast tego spowoduje użycie dynamicznego wysyłania i odniesienie do klasy bieżącego wystąpienia, w którym właściwość statyczna może mieć odziedziczoną wartość, ale może również zostać zastąpiona.Jest to zgodne z zachowaniem języka Python, w którym można wybrać odwołanie do właściwości statycznych za pośrednictwem nazwy klasy lub instancji
self
.Jeśli oczekujesz, że właściwości statyczne nie będą zastępowane (i zawsze odwołują się do jednej z bieżącej klasy), tak jak w Javie , użyj jawnego odwołania.
źródło
class
składni), nie ma różnicy w definicji metody. To tylko kwestia tego, jak to sprawdzisz, poprzez dziedziczonąconstructor
właściwość lub bezpośrednio po jej nazwie.Property 'staticProperty' does not exist on type 'Function'
Natknąłem się na ten wątek, szukając odpowiedzi na podobny przypadek. Zasadniczo można znaleźć wszystkie odpowiedzi, ale nadal trudno jest wydobyć z nich najważniejsze informacje.
Rodzaje dostępu
Załóżmy, że klasa Foo prawdopodobnie pochodzi z jakiejś innej (ych) klasy (klas) z prawdopodobnie większą liczbą klas pochodnych.
Następnie uzyskujesz dostęp
this.method()
this.property
Foo.method()
Foo.property
this.constructor.method()
this.constructor.property
this.method()
this.property
Foo.method()
Foo.property
Foo.prototype.method.call( this )
Object.getOwnPropertyDescriptor( Foo.prototype,"property" ).get.call(this);
tło
this
odnosi się do bieżącej instancji.super
zasadniczo odnosi się do tej samej instancji, ale w pewnym stopniu adresuje metody i metody pobierające napisane w kontekście jakiejś klasy, która jest obecnie rozszerzana (przy użyciu prototypu prototypu Foo).this.constructor
.this
jest dostępny, aby bezpośrednio odwołać się do definicji bieżącej klasy.super
nie odnosi się również do jakiejś instancji, ale do statycznych metod i metod pobierających napisanych w kontekście jakiejś klasy, która jest obecnie rozszerzana.Wniosek
Wypróbuj ten kod:
źródło
Own non-overridden instance method/getter / not possible by intention unless using some workaround
--- To prawdziwa szkoda. Moim zdaniem to wada ES6 +. Może powinien zostać zaktualizowany, aby umożliwić proste odwoływanie się domethod
- tjmethod.call(this)
. Lepiej niżFoo.prototype.method
. Babel / itp. można zaimplementować używając NFE (nazwane wyrażenie funkcyjne).method.call( this )
jest prawdopodobnym rozwiązaniem, z wyjątkiem tego, żemethod
nie jest wówczas powiązany z żądaną podstawową „klasą”, a zatem nie jest nieprzesłoniętą metodą instancji / pobierającą . W ten sposób zawsze można pracować z metodami niezależnymi od klas. Niemniej jednak nie sądzę, aby obecny projekt był taki zły. W kontekście obiektów klasy wywodzącej się z klasy bazowej Foo mogą istnieć dobre powody do przesłonięcia metody instancji. Ta zastąpiona metoda może mieć dobre powody, aby wywołać jejsuper
implementację lub nie. Każdy przypadek jest kwalifikowalny i należy go przestrzegać. W przeciwnym razie skończyłoby się to złym projektem OOP.arguments.callee
lub NFE.this
). Brzmi to jak próba połączenia korzyści płynących z arytmetyki wskaźników czystego C z C # wyższego poziomu. Tak z ciekawości: do czego byś użyłarguments.callee
w czysto zaprojektowanym kodzie OOP?this.inherited(currentFn, arguments);
- gdziecurrentFn
jest odniesieniem do aktualnie wykonywanej funkcji. Brak możliwości bezpośredniego odniesienia się do aktualnie wykonywanej funkcji sprawia, że jest ona trochę zawiły w TypeScript, który bierze składnię klasy z ES6.Jeśli planujesz zrobić jakikolwiek spadek, to polecam
this.constructor
. Ten prosty przykład powinien zilustrować, dlaczego:test1.callPrint()
zalogujeConstructorSuper Hello ConstructorSuper!
się do konsolitest2.callPrint()
zalogujeConstructorSub Hello ConstructorSub!
się do konsoliNazwana klasa nie poradzi sobie dobrze z dziedziczeniem, chyba że jawnie przedefiniujesz każdą funkcję, która odwołuje się do nazwanej Class. Oto przykład:
test3.callPrint()
zalogujeNamedSuper Hello NamedSuper!
się do konsolitest4.callPrint()
zalogujeNamedSuper Hello NamedSub!
się do konsoliZobacz wszystkie powyższe uruchomione w Babel REPL .
Widać z tego, że
test4
nadal uważa, że jest to super klasa; w tym przykładzie może się wydawać, że nie jest to wielka sprawa, ale jeśli próbujesz odwoływać się do funkcji składowych, które zostały nadpisane lub do nowych zmiennych składowych, znajdziesz się w tarapatach.źródło