2012-02-23 12 views
5

Używam wzorca modułu JavaScript, aby spróbować zaimplementować funkcję wyliczania podobną do języka C#. Mam dwa sposoby, o których obecnie myślę, aby wdrożyć tę funkcjonalność, ale nie rozumiem wszystkich zalet i zalet jednego sposobu w porównaniu do drugiego.Moduł JavaScript Pamięć modelu i wydajność

Oto realizacja 1:

var MyApp = (function (app) { 

    // Private Variable 
    var enums = { 
     ActionStatus: { 
      New: 1, 
      Open: 2, 
      Closed: 3 
     } 
    }; 

    // Public Method 
    app.getEnum = function (path) { 
     var value = enums;    
     var properties = path.split('.'); 
     for (var i = 0, len = properties.length; i < len; ++i) { 
      value = value[properties[i]]; 
     } 
     return value; 
    }; 

    return app; 

})(MyApp || {}); 

// Example usage 
var status = MyApp.getEnum("ActionStatus.Open"); 

A teraz realizacja 2:

var MyApp = (function (app) { 

    // Public Property 
    app.Enums = { 
     ActionStatus: { 
      New: 1, 
      Open: 2, 
      Closed: 3 
     } 
    }; 

    return app; 

})(MyApp || {}); 

// Example usage 
var status = MyApp.Enums.ActionStatus.Open; 

Główna różnica polega na zastosowaniu zmiennej "prywatny" vs "Publiczny" własności przechowywać teksty stałe. Wydaje mi się, że implementacja 1 jest nieco wolniejsza, ale nie byłem pewien, czy zachowanie wyliczeń jako "prywatnych" zmniejszyło zużycie pamięci. Czy ktoś może wyjaśnić różnicę w ilości pamięci i wydajności pamięci dla tych dwóch (jeśli są)? Wszelkie inne sugestie/porady są mile widziane.

Odpowiedz

4

... ale nie byłem pewien, czy utrzymując stałe teksty, jak „prywatny” zmniejsza zużycie pamięci

Przeciwieństwem, jeśli w ogóle: Trzeba jeszcze mieć stałe teksty obiekt, i musisz mieć dostęp do funkcji.

Pod względem szybkości, nie martwię się o to. Dodane wywołanie funkcji nie spowoduje żadnej rzeczywistej różnicy (I looked into it, gdy martwisz się o używanie nowego forEach i tym podobnych, a nawet na IE6 z silnikiem JS o dużej pojemności, to po prostu nie ma znaczenia).

W ciągu kilku lat, prawdopodobnie będziesz w stanie mieć najlepsze z obu światów: wyliczenia, które są tylko do odczytu, dzięki ECMAScript5 za Object.defineProperties funkcji:

var Enums = Object.defineProperties({}, { 
    ActionStatus: { 
     value: Object.defineProperties({}, { 
      New: {value: 1}, 
      Open: {value: 2}, 
      Closed: {value: 3} 
     }) 
    } 
}); 

// Usage 
var n = Enums.ActionStatus.New; // 1 

Domyślnie, właściwości utworzonych za pomocą definePropertiestylko do odczytu.

W zasadzie możesz to teraz zrobić, jeśli dodasz podkładkę ES5 ", aby utworzyć Object.defineProperties w przeglądarkach, które nie mają jeszcze natywnej wersji. Wersja "shimmed" tworzyłaby właściwości odczytu i zapisu, ponieważ tylko natywnie obsługiwana wersja może naprawdę tworzyć właściwości tylko do odczytu, ale możesz teraz napisać kod i wiedzieć, że będzie działał jak chcesz w nowoczesnych przeglądarkach (około połowa wszyscy internauci mają je teraz), wciąż pracując, tylko z mniejszą solidnością, na mniej nowoczesnych.

Oczywiście, EMCAScript6 może zająć jeszcze więcej rzeczy, ale to nadal jest przyszłość.

+0

Dzięki za poświęcenie czasu na odpowiedź i na informacje ES5. Czy wiesz w kategoriach zarządzania pamięcią przeglądarki, w jaki sposób implementacja 1 przechowuje swoją prywatną zmienną a przechowywanie jej własności publicznej w implementacji 2? Próbowałem profilować zużycie pamięci, ale wszystko, co mogłem odkryć, to to, że implementacja 2 spowodowała zwiększenie rozmiaru obiektu MyApp, natomiast implementacja 1 nie. Ale wiem, że implementacja 1 musi gdzieś przechowywać odniesienie do zmiennej prywatnej. –

+0

@steve_ut: Jest przechowywany w czymś nazwanym (głęboki oddech) * obiektem wiążącym zmiennej * z * kontekstem wykonania * połączenia z anonimową funkcją, której używasz do utworzenia obiektu. * (whew) * :-) To jest terminologia [ES5 spec] (http://es5.github.com) ([link kanoniczny] (http://www.ecma-international.org/publications/standards/Ecma- 262.htm)). Każde wywołanie funkcji otrzymuje zmienny obiekt wiążący, który zawiera args do funkcji, jej lokalne vars i kilka innych rzeczy jako właściwości.Opis ze starszą terminologią tutaj * [Zamknięcia nie są skomplikowane] (http://goo.gl/OzIQY) *. –

+0

@steve_ut: A właściwie, aby być bardziej poprawnym, jest przechowywany w ogólnej puli pamięci, a obiekt wiążący zmienne ma do niej odniesienie. To także bardziej poprawny sposób patrzenia na obiekt 'MyApp'; Jakiekolwiek narzędzie używane do mapowania rozmiaru 'MyApp' dostarcza tam trochę uproszczonych informacji. JavaScript dotyczy wszystkich obiektów w puli pamięci z odniesieniami do siebie. Obiekt 'MyApp' z implementacji 2 w rzeczywistości nie * zawiera * obiektu, do którego odwołuje się' app.Enums', tak jak nie ma to w przypadku implementacji 1. –

Powiązane problemy