2012-03-19 21 views
29

staram się poprawić moje rozumienie globalnej przestrzeni nazw w JavaScript i jestem ciekawy o kilku rzeczach:zrozumienia javascript globalnej przestrzeni nazw i zamknięć

  1. tam jest „Bóg” (czyli rodzic) obiekt, że wszystkie obiekty (ponieważ wszystkie rzeczy oprócz prymitywów są obiektami) do odpowiedzi, a jeśli tak, to obiekt byłby "okno"?

  2. Dlaczego nie jest dobrym pomysłem posiadanie vars/funkcje na poziomie globalnym?

  3. jeśli naprawdę jest złym pomysłem posiadanie vars/funkcji w globalnym zasięgu, to czy zamknięcie byłoby najlepszym sposobem na uniknięcie tego? Przykład:

    function parent(){ 
        var x = 'some value';//this var would be considered global to all children functions but not in the true global namespace 
        function child1(){ 
         x.someMethod() 
        } 
        function child2(){ 
         x*something; 
        } 
        function child3(){ 
         x+=something; 
         child2() 
         child1() 
        } 
        child3() 
    } 
    parent() 
    

Odpowiedz

24
  1. Czy god (to jest dominująca) obiektu?

    Yes. Bardziej technicznie, jest to obiekt globalny, do którego należą wszystkie te prymitywy; tak się składa, że ​​w przeglądarce obiekt globalny jest obiektem.

    > window.String === String; 
    true 
    
  2. Dlaczego jest to zły pomysł, aby mieć Vars/funkcje na poziomie globalnym?

    Ponieważ jeśli dodajesz wiele bibliotek/skryptów firm trzecich, wszystkie mają ten sam obiekt globalny, istnieje ryzyko kolizji nazw. Jest to prawdziwy problem ze wszystkimi bibliotekami, które używają $ jako aliasu (jQuery, Prototype i innych).

  3. Jeśli naprawdę źle jest mieć vary/funkcje w skali globalnej, to czy zamknięcie byłoby najlepszym sposobem na uniknięcie tego?

    x nie należy uważać za globalny. Jest to część zamknięcia utworzonego przez deklarowanie funkcji potomnych wewnątrz funkcji parent(). Część fragmentu kodu jest parent() globalna; co się stanie, jeśli jakiś inny kod zostanie ponownie zadeklarowany jako parent()? To byłoby lepsze:

    (function() { 
    
    function parent(){ 
        var x = 'some value'; 
        function child1(){ 
         x.someMethod() 
        } 
        function child2(){ 
         x*something; 
        } 
        function child3(){ 
         x+=something; 
         child2() 
         child1() 
        } 
        child3() 
    } 
    parent() 
    
    }()); 
    

    Fakt x jest dostępny w ramach funkcji dziecko nie jest złe; powinieneś był napisać te funkcje samemu, więc powinieneś być świadomy o istnieniu x. Pamiętaj, że jeśli ponownie zadeklarujesz x w ramach funkcji podrzędnych z var, nie wpłynie to na x w parent().

+0

dla xi ment, że jest globalne funkcjom dzieci, ale nie do globalnego obiektu, co oznacza, że ​​wszystkie funkcje dziecko może uzyskać do niego dostęp bez niego bycie przeszłym jako argumentem – zero

+0

@codewombat: ale normalnie zadeklarowałbyś tylko funkcję w ramach innej funkcji **, ponieważ ** potrzebujesz jej, aby uzyskać dostęp do zmiennych w tym zakresie. – Matt

+0

ponieważ masz funkcję macierzystego wykonywania, jeśli któryś z kodu wykonuje manipulację domem, czy powinien on zostać wywołany na dole węzła body? – zero

5
  1. Tak, w środowisku przeglądarki "Bogiem obiekt" jest okno.Zwykle nazywa się obiekt globalny , ale nie jest to obiekt , który jest obiektem;) W środowiskach niezwiązanych z przeglądarką, takich jak nodejs, obiekt globalny może używać innej nazwy niż okno.

  2. Jeśli umieścisz wszystko jako globalne, ryzykujesz wpadanie w zderzające się nazwy. Jest też kwestia encapsulation - innymi słowy, umieszczając zmienne tylko w zakresie, gdzie jest to potrzebne, Twój kod jest zwykle lepszy.

  3. Tak, jest to preferowane podejście. Można również użyć IIFE „s

+0

czy IIFE nie spowodowałoby błędu, jeśli w jego obrębie jest kod modyfikujący domenę lub czy lepiej jest wywołać js na dole węzła body (aby upewnić się, że załadowany został cały HTML)? – zero

+0

nazwa globalnego obiektu jest przyjemna, ale "obiekt bogów" brzmi tak fajnie: D – zero

+2

Tak, IIFE _ może spowodować błąd, jeśli kod w nim próbował uzyskać dostęp do DOM, zanim był gotowy. Albo umieszczając IIFE na dole strony, albo używając jQuery '$ (document) .ready (function() {...});' – skube

3
  1. O ile mi wiadomo, powiedziałbym tak, okno jest obiekt nadrzędny. Jednak wewnątrz elementu iframe znajduje się własny obiekt okna, inny niż okno otaczające, do którego można uzyskać dostęp przez okno.parent

  2. To zły pomysł, aby mieć DUŻO globalnego var ze względu na potencjalną kolizję nazwy, a zatem trudny do wykrycia. błędy. Generalnie bezpieczniej jest zaprojektować przestrzeń nazw (zob. z $ z jQuery, itp.) I modularyzować kod.

  3. Uważaj, parent to potencjalnie istniejące pole okna. Tą aplikacją jest funkcja, której celem jest ta sama obserwacja niż w 2).

+0

, więc czy istnieje sposób na "błąd dowodu" funkcji nadrzędnej, ponieważ jest to jedyny obiekt globalny? – zero

+1

wzór modułu na przykład: http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Dthth – Nicocube

2

Jeśli POTRZEBA umieścić zmiennych w globalnej przestrzeni nazw, i prawdopodobnie będzie w pewnym momencie utworzenia pojedynczej zmiennej obiektu i dodać do niego inne zmienne jak właściwości lub metody. Nadaj obiektowi nazwę, która prawdopodobnie nie będzie używana przez nikogo innego (wprawdzie w tym miejscu pojawiają się problemy związane z kolizją, ale można to złagodzić przez staranne, wystandaryzowane nazewnictwo).

np. Zamiast:

var thing1 = 'table'; 
var anotherthing = 'chair'; 
var mypet = 'dog'; 
var count = 4; 
var show_something: function(_txt) { return _txt.trim(); }; 

Wykonaj:

var cmjaimet_obj = { 
    thing1: 'table', 
    anotherthing: 'chair', 
    mypet: 'dog', 
    count: 4, 
    show_something: function(_txt) { return _txt.trim(); } 
}; 

Później nazywają je jako właściwości:

przykład Zamiast:

count += 2; 
anotherthing = 'sofa'; 
console.log(show_something('Thing: ' + anotherthing)); 

Wykonaj:

cmjaimet_obj.count += 2; 
cmjaimet_obj.anotherthing = 'sofa'; 
console.log(cmjaimet_obj.show_something('Thing: ' + cmjaimet_obj.anotherthing)); 
-1
var com = {}; 
com.Bookstore = {}; 
com.Bookstore.Book = { 
    title: 'my book', 
    genre: 'fiction' 
}; 
com.Bookstore.Author = { 
    firstName: 'R', 
    lastName: 'D' 
} 
Powiązane problemy