2012-06-15 16 views
7

Czytałem wcześniej, jak "Utworzyć bibliotekę JavaScript" i natknąłem się na te fragmenty kodu, które sprawiają, że chcę zgrać moje włosy.W jaki sposób działają te fragmenty kodu?

Oto kod, który dostał mój mózg w węzłach:

if (window === this) { 
    return new _(id); 
} 

_ (id) jest tylko nazwa funkcji, w której zawarty jest ten kod. Oto reszta kodu, jeśli chcesz sam się nad tym zastanowić.

function _(id) { 

// About object is returned if there is no 'id' parameter 
var about = { 
    Version: 0.5, 
    Author: "Michael Jasper", 
    Created: "Fall 2010", 
    Updated: "23 November 2011" 
}; 

if (id) { 

    // Avoid clobbering the window scope: 
    // return a new _ object if we're in the wrong scope 
    if (window === this) { 
     return new _(id); 
    } 

    // We're in the correct object scope: 
    // Init our element object and return the object 
    this.e = document.getElementById(id); 
    return this; 
    } else { 
    // No 'id' parameter was given, return the 'about' object 
    return about; 
    } 
}; 

Nigdy wcześniej nie widziałem "zwróć nową funkcję", ale chciałbym zrozumieć, jak to działa.

Drugi kawałek kodu:

_.prototype = { 
    hide: function() { 
      this.e.style.display = 'none'; 
      return this; 
    } 

    show: function() { 
      this.e.style.display = 'inherit'; 
      return this; 
    } 
}; 

wiem, że ten kod dodaje nowe metody do obiektu _ ale dlaczego oni to „powrót”? Próbowałem tego bez niego i działało dobrze.

Ostatnią rzeczą, link do artykułu jest http://www.mikedoesweb.com/2012/creating-your-own-javascript-library/

+0

Return to? Więc może po tym możesz dodać coś więcej? Po prostu zgadywanie – Anonymous

+6

Funkcja 'return this' włącza łańcuch, tak jak w' magic(). Do(). Stuff() '. –

+0

tak, łańcuchowanie jest tym, co miałem na myśli ,, to jak jquery, ale jquery jest nieco bardziej skomplikowany i zwraca wiele obiektów. – Anonymous

Odpowiedz

16

Pierwszy kawałek kodu jest zasadniczo próbuje wykryć jak funkcja „konstruktor” został nazwany ...

w javascript, można użyć funkcji do utworzenia obiektu na dwa sposoby:

function _(id) { 
    this.someProperty = "stuff"; 
    //Do more stuff to "this" 
    return this; 
} 

//in this scenario, the "this" object will be the window object 
var myObject = _(id); 
console.log(window.someProperty); //outputs "stuff"; 
console.log(myObject.someProperty); //outputs "stuff"; 

//in this scenario, the "this" object is what get's actually returned... 
var myObject = new _(id); 
console.log(window.someProperty); //outputs "undefined" 
console.log(myObject.someProperty); //outputs "stuff" 

zatem sprawdzanie na

if (window === this) { 
    return new _(id); 
} 

jest po prostu tam, aby upewnić się, że nie przypadkowo wywołać konstruktor bez słowa kluczowego new. byłoby to złe, ponieważ każda właściwość przypisana do obiektu natychmiast zostałaby przypisana do przestrzeni nazw window ... która byłaby zła.


jak do drugiego pytania, autor używa return this; na końcu każdej metody jako fluent interface design pattern

ten pozwala na wygodne i ładne patrząc manipulacji obiektu. Typowym przykładem tego jest jQuery, gdzie można metody łańcuch na jednym obiekcie ...

$(".some-css-selector").click(function() { 
    ... do something to the selected objects during the "click" event 
}).keyup(function() { 
    ... do something to the same objects during the "keyup" event 
}); 

EDIT: trochę więcej dodatkowych informacji w odpowiedzi na komentarze W3Geek jest poniżej:

od Douglas Książka Crockforda "Javascript: The Good Parts" (całkiem dobra lektura, jeśli wchodzisz do JS ... tylko 70 stron, ale każda z nich jest warta przeczytania). new operator


Javascript w tworzy nowy obiekt, która dziedziczy członka prototypu argumentu, a następnie wywołuje argument, oprawa nowego obiektu do this.To daje operandowi (który lepiej byłby funkcją konstruktora) szansę na spersonalizowanie nowego obiektu, zanim zostanie on zwrócony do requestera.

Pominięcie użyć `nowego operatora, to zamiast dostać zwykłe wywołanie funkcji, a to wiąże się z globalnego obiektu zamiast do nowego obiektu. Oznacza to, że twoja funkcja będzie zmieniać globalne zmienne podczas próby zainicjowania nowych członków. To bardzo zła rzecz.

...

Konstruktorzy są funkcjami, które są przeznaczone do stosowania z przedrostkiem new. Prefiks new tworzy nowy obiekt na podstawie prototypu funkcji i wiąże ten obiekt z parametrami domniemanymi funkcjami. Jeśli nie podasz prefiksu new, nowy obiekt nie zostanie utworzony, a this zostanie powiązany z obiektem globalnym. To poważny błąd.


+0

W zasadzie "to" spowodowałoby zanieczyszczenie globalnego zakresu, gdybyśmy użyli go niepoprawnie i aby tamto miejsce zostało "sprawdzone", tak? Moje pytanie brzmi, co jest nie tak z przestrzeni nazw okna? Widzę tak wiele o tym, jak to źle, ale nigdy dlaczego. – W3Geek

+0

prawidłowe. dodawanie właściwości do obiektu "window" jest złe, ponieważ istnieje wiele innych frameworków, które mają do niego dostęp (i używają go), na przykład ludzie modyfikują obiekt 'window.location.href' (aktualny adres URL przeglądarki) cały czas "nawigować" do nowej strony ... jeśli nagle dodałeś właściwość location do twojego obiektu _ _, to całkowicie zablokuje właściwość window.location ... generalnie powinieneś wystarczy umieścić rzeczy, które kontrolują w swojej własnej przestrzeni nazw, aby mieć pewność, że nie ma żadnych skutków ubocznych –

+2

Uwaga: nie wydają się być kilka przyzwoitych odpowiedzi tutaj [na „wyciek” zmienne w globalnej przestrzeni nazw] (http://stackoverflow.com/questions/5951228/what-is-meant-by-leaking-into-global-scope). Na ogół jest dużo dyskusji na ten temat, które nie pasowałyby do komentarza :) –

6

return this daje zdolność do wywołania metod łańcuch. Możesz zrobić naprawdę fajne i użyteczne rzeczy, takie jak _.show().hide(). :)

Powiązane problemy