W Javascript istnieje kilka wyraźnie widocznych technik tworzenia i zarządzania klasami / przestrzeniami nazw w javascript.
Jestem ciekawy, jakie sytuacje uzasadniają użycie jednej techniki w porównaniu do drugiej. Chcę wybrać jeden i trzymać się go z przodu.
Piszę kod korporacyjny, który jest utrzymywany i współdzielony przez wiele zespołów, i chcę wiedzieć, jaka jest najlepsza praktyka podczas pisania możliwego do utrzymania javascript?
Wolę samoczynne wykonywanie anonimowych funkcji, ale jestem ciekawy, co głosuje społeczność w sprawie tych technik.
Prototyp:
function obj()
{
}
obj.prototype.test = function() { alert('Hello?'); };
var obj2 = new obj();
obj2.test();
Samozamykająca się funkcja anonimowa:
//Self-Executing Anonymous Function
(function( skillet, $, undefined ) {
//Private Property
var isHot = true;
//Public Property
skillet.ingredient = "Bacon Strips";
//Public Method
skillet.fry = function() {
var oliveOil;
addItem( "\t\n Butter \n\t" );
addItem( oliveOil );
console.log( "Frying " + skillet.ingredient );
};
//Private Method
function addItem( item ) {
if ( item !== undefined ) {
console.log( "Adding " + $.trim(item) );
}
}
}( window.skillet = window.skillet || {}, jQuery ));
//Public Properties
console.log( skillet.ingredient ); //Bacon Strips
//Public Methods
skillet.fry(); //Adding Butter & Fraying Bacon Strips
//Adding a Public Property
skillet.quantity = "12"; console.log( skillet.quantity ); //12
//Adding New Functionality to the Skillet
(function( skillet, $, undefined ) {
//Private Property
var amountOfGrease = "1 Cup";
//Public Method
skillet.toString = function() {
console.log( skillet.quantity + " " +
skillet.ingredient + " & " +
amountOfGrease + " of Grease" );
console.log( isHot ? "Hot" : "Cold" );
};
}( window.skillet = window.skillet || {}, jQuery ));
//end of skillet definition
try {
//12 Bacon Strips & 1 Cup of Grease
skillet.toString(); //Throws Exception
} catch( e ) {
console.log( e.message ); //isHot is not defined
}
Uważam, że powinienem wspomnieć, że Self-Executing Anonymous Function to wzorzec używany przez zespół jQuery.
Aktualizacja
Kiedy zadałem to pytanie, naprawdę nie dostrzegłem znaczenia tego, co próbowałem zrozumieć. Prawdziwym problemem jest to, czy użyć nowego do tworzenia instancji swoich obiektów, czy też używać wzorców, które nie wymagają konstruktorów / użycia new
słowa kluczowego.
Dodałem własną odpowiedź, ponieważ moim zdaniem powinniśmy korzystać ze wzorów, które nie używają new
słowa kluczowego.
Aby uzyskać więcej informacji, zobacz moją odpowiedź.
źródło
Odpowiedzi:
Samoczynne anonimowe funkcje służą do automatyzacji wykonywania skryptów bez przechwytywania zdarzeń zewnętrznych (np. Window.onload).
W tym przykładzie jest on używany do utworzenia klasycznego wzorca modułu, którego głównym celem jest wprowadzenie przestrzeni nazw do środowiska globalnego i zapewnienie enkapsulacji dla wszystkich właściwości wewnętrznych, które nie są „eksportowane” lub dołączane do przestrzeni nazw.
Z drugiej strony modyfikacja prototypu obiektów służy do ustanowienia dziedziczenia (lub rozszerzenia tubylców). Ten wzór służy do tworzenia obiektów 1: n o wspólnych metodach lub właściwościach.
Nie powinieneś wybierać jednego wzorca zamiast drugiego, ponieważ wykonują one różne zadania. Jeśli chodzi o przestrzeń nazw, właściwym wyborem jest funkcja samowykonywania.
źródło
Oto wzór, który właśnie zacząłem używać (do wczoraj stosowałem jego odmiany):
Kilka przemyśleń na ten temat:
(anonymous)
śladów w śladzie stosu debuggera, ponieważ wszystko jest nazwane (bez anonimowych funkcji).Jedynym czasem, którego
prototype
użyłbym naprawdę, jest zdefiniowanie dziedziczenia.źródło
function clone(obj){return this typeof 'clone' ? this : new clone(clone.prototype=obj)}
prototype
metodą, którą sugerujesz, to (chyba że istnieje metoda, której nie znam, co może się zdarzyć), że tracisz zdolność do enkapsulacji atrybutów, co oznacza, że wszystko jest jawne (co nie jest końcem świata , tylko osobiste preferencje).Używam prototypów, ponieważ są one czystsze i zgodne ze standardowymi wzorcami dziedziczenia. Funkcje samo-wywołujące są idealne do tworzenia przeglądarki lub sytuacji, w której nie wiesz, gdzie jest wykonywany kod, ale w przeciwnym razie jest to tylko szum.
Przykład:
źródło
Wybrałbym funkcję samowykonywania, ale z niewielką różnicą:
Jeśli uważam, że to podejście jest znacznie bardziej przejrzyste, ponieważ oddzielam zwracaną zmienną globalną od jakichkolwiek parametrów wejściowych (takich jak jQuery) (sposób, w jaki ją napisałeś, jest równoważny zwracaniu void i użyciu parametru ref w C #, co uważam za nieco wyłączone, lub przekazywanie wskaźnika do wskaźnika i ponowne przypisywanie go w C ++). Gdybym wtedy miał dołączyć dodatkowe metody lub właściwości do klasy, użyłbym dziedziczenia prototypowego (na przykład metodą $ .extend jQuery'ego, ale łatwo jest stworzyć własne rozszerzenie ()):
W ten sposób masz wyraźne rozróżnienie między dodanymi metodami a metodami oryginalnymi.
źródło
Przykład na żywo
Za pomocą IIFE można emulować „zakres modułu” wokół kodu. Następnie możesz po prostu używać obiektów tak jak zwykle.
Nie „emuluj” stanu prywatnego za pomocą zamknięć, ponieważ ma to dużą karę pamięci.
Jeśli piszesz aplikację korporacyjną i chcesz utrzymać zużycie pamięci poniżej 1 GB, unikaj niepotrzebnego używania zamknięć do przechowywania stanu.
źródło
console
a globalnąconsole
stanowi mikrooptymalizację. Warto to zrobić, aby zminimalizować,console
ale to inna sprawaAktualizacja Mam teraz znacznie lepsze zrozumienie javascript i uważam, że mogę właściwie odpowiedzieć na to pytanie. Myślę, że był to źle sformułowany, ale bardzo ważny temat javascript.
Wzorzec samowystarczalnej funkcji anonimowej nie jest tym, który wymaga użycia nowego słowa kluczowego, jeśli unikniesz użycia tego poza funkcjami. Zgadzam się z pomysłem, że używanie nowego jest starą techniką i powinniśmy raczej starać się stosować wzorce, które unikają użycia nowego.
Samoczynnie wykonująca się funkcja anonimowa spełnia te kryteria.
Odpowiedź na to pytanie jest subiektywna, ponieważ w javascript jest tak wiele stylów kodowania. Jednak na podstawie moich badań i doświadczenia zaleciłbym wybranie użycia funkcji anonimowego wykonywania w celu zdefiniowania interfejsów API i unikania używania nowych, gdy tylko jest to możliwe.
źródło
Oto jak bym go o to
IIFE
SelfExecutingFunction
, aby przedłużyćMyclass
zMyclass.anotherFunction()
;źródło