To jest JavaScript. Gdy stajesz się lepszy, zauważysz, że często znajduje się środkowa droga, która pomaga negować takie dylematy. Poza tym naprawdę nie ma znaczenia, czy jakiś nieobsługiwany „typ” zostanie złapany przez coś, czy ulegnie awarii, gdy ktoś spróbuje go użyć, ponieważ nie ma kompilacji w czasie wykonywania. Jeśli użyjesz go źle, psuje się. Próba ukrycia, że się zepsuła lub sprawiła, że działała w połowie, kiedy się zepsuła, nie zmienia faktu, że coś jest zepsute.
Więc zjedz swoje ciasto i zjedz je, a także naucz się unikać pomyłek typu i niepotrzebnego łamania, utrzymując wszystko naprawdę, naprawdę oczywiste, jak w dobrze nazwanym i ze wszystkimi właściwymi szczegółami we właściwych miejscach.
Przede wszystkim gorąco zachęcam do przyzwyczajenia się do ustawiania kaczek z rzędu, zanim będzie trzeba sprawdzać typy. Najsmuklejszym i najbardziej wydajnym (ale nie zawsze najlepszym w przypadku rodzimych konstruktorów) jest najpierw uderzenie w prototypy, aby twoja metoda nie musiała nawet przejmować się obsługiwanym typem.
String.prototype.pullRabbit = function(){
//do something string-relevant
}
HTMLElement.prototype.pullRabbit = function(){
//do something HTMLElement-relevant
}
Magician.pullRabbitFrom = function(someThingy){
return someThingy.pullRabbit();
}
Uwaga: Powszechnie uważa się za złą formę robienia tego z Object, ponieważ wszystko dziedziczy po Object. Osobiście też unikałbym Funkcji. Niektórzy mogą odczuwać zaniepokojenie dotykaniem prototypu dowolnego natywnego konstruktora, co może nie być złą polityką, ale przykład może nadal służyć podczas pracy z własnymi konstruktorami obiektów.
Nie martwiłbym się tym podejściem w przypadku metody o konkretnym zastosowaniu, która prawdopodobnie nie zablokuje czegoś z innej biblioteki w mniej skomplikowanej aplikacji, ale dobrym instynktem jest unikanie twierdzenia, że zbyt wiele metod rodzimych w JavaScript, jeśli nie musisz, chyba że normalizujesz nowsze metody w nieaktualnych przeglądarkach.
Na szczęście zawsze możesz po prostu wstępnie odwzorować typy lub nazwy konstruktorów na metody (strzeż się IE <= 8, który nie ma <object> .constructor.name, wymagając, abyś go przeanalizował z wyników toString z właściwości konstruktora). Wciąż sprawdzasz nazwę konstruktora (typeof jest dość bezużyteczny w JS podczas porównywania obiektów), ale przynajmniej czyta o wiele ładniej niż gigantyczna instrukcja switch lub łańcuch / / else w każdym wywołaniu metody do czegoś, co może być szerokie różnorodność obiektów.
var rabbitPullMap = {
String: ( function pullRabbitFromString(){
//do stuff here
} ),
//parens so we can assign named functions if we want for helpful debug
//yes, I've been inconsistent. It's just a nice unrelated trick
//when you want a named inline function assignment
HTMLElement: ( function pullRabitFromHTMLElement(){
//do stuff here
} )
}
Magician.pullRabbitFrom = function(someThingy){
return rabbitPullMap[someThingy.constructor.name]();
}
Lub stosując tę samą metodę mapowania, jeśli chcesz uzyskać dostęp do komponentu „ten” różnych typów obiektów, aby korzystać z nich tak, jakby były metodami bez dotykania odziedziczonych prototypów:
var rabbitPullMap = {
String: ( function(obj){
//yes the anon wrapping funcs would make more sense in one spot elsewhere.
return ( function pullRabbitFromString(obj){
var rabbitReach = this.match(/rabbit/g);
return rabbitReach.length;
} ).call(obj);
} ),
HTMLElement: ( function(obj){
return ( function pullRabitFromHTMLElement(obj){
return this.querySelectorAll('.rabbit').length;
} ).call(obj);
} )
}
Magician.pullRabbitFrom = function(someThingy){
var
constructorName = someThingy.constructor.name,
rabbitCnt = rabbitPullMap[constructorName](someThingy);
console.log(
[
'The magician pulls ' + rabbitCnt,
rabbitCnt === 1 ? 'rabbit' : 'rabbits',
'out of her ' + constructorName + '.',
rabbitCnt === 0 ? 'Boo!' : 'Yay!'
].join(' ');
);
}
Dobrą ogólną zasadą w każdym języku IMO jest próba uporządkowania szczegółów rozgałęzienia, zanim dojdziesz do kodu, który faktycznie pociąga za spust. W ten sposób można łatwo zobaczyć wszystkich graczy zaangażowanych w ten najwyższy poziom API, aby uzyskać przyjemny przegląd, ale także znacznie łatwiej jest ustalić, gdzie można znaleźć szczegóły, które mogą być dla kogoś ważne.
Uwaga: wszystko to nie zostało przetestowane, ponieważ zakładam, że nikt tak naprawdę nie ma do tego zastosowania RL. Jestem pewien, że są literówki / błędy.