2013-06-21 6 views
7

Niedawno użyłem little utility library Johna Resiga, o nazwie inherit.js. Zwykle staram się zrozumieć główne części bibliotek, których używam, i po wielu drapaniach głowy w końcu zrozumiałem twarde fragmenty kodu (a mianowicie, jak mógł nazwać odpowiednią metodę super klasy).Weird regex in inherit.js (autor John Resig) - dlaczego, co i jak?

1% trochę nie rozumiem dotyczy regex

fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/; 
  1. regex/xyz/jest testowany przed funkcji. Zarówno MSDN, jak i MDN określają, że test przyjmuje jako argument łańcuch. Brak wzmianki o funkcji, ale ponieważ nie ma błędów w konsoli, myślę, że musi lecieć, ale jak to działa?
  2. Następnym terminalem WTF jest to, że treść funkcji to xyz;. Ta funkcja nie może zostać wykonana, ponieważ w przeciwnym razie powstałaby "ReferenceError: xyz is not defined". Dobrze? Więc co to robi?
  3. Jeśli wynik testu jest prawdziwy, to fnTest jest równe regex, który sprawdza _super na granicy słowa, w przeciwnym razie regex pasuje do czegokolwiek. Podwójny WTF; jeszcze raz, jak i dlaczego.

Później jest powiązany fragment kodu, w którym używane jest wyrażenie regularne.

// Check if we're overwriting an existing function 
    prototype[name] = typeof prop[name] == "function" && 
    typeof _super[name] == "function" && fnTest.test(prop[name]) 
     ? aFunctionThatCanCallSuper /* Lots of code */ 
     : prop[name]; 

Trochę tu zastanawiam się, to jest fnTest.test(prop[name]). Rozumiem wszystkie inne testy, które sprawdzają, czy właściwość istnieje, jest funkcją itp., Ale nie to, co robi test regex. Ktoś?

+1

[Zrozumienie Johna Resig za 'Proste JavaScript Inheritance'] (http://blog.buymeasoda.com/ understanding-john-resigs-simple-javascript-i /) – Andreas

+0

@Andreas: Wow, żałuję, że nie znalazłem tego wcześniej, po prostu musiałem to rozszyfrować, ale wydaje mi się, że moje wnioski są poprawne. – elclanrs

+0

Nawet nie warta opublikowania mojej odpowiedzi, ten link wydaje się idealną odpowiedzią. Zgaduję, że gdybyś przerobił tę bibliotekę _today_, to sprawdzanie nie jest konieczne, biorąc pod uwagę, że nowoczesne przeglądarki będą serializować poprawnie. – elclanrs

Odpowiedz

6

co:

test zajmuje tylko ciągi jako wejście, a więc funkcja będzie toString ed, jak będzie każdy inny obiekt, który nie jest ciągiem. xyz nie jest interpretowany jako zmienna, ale jako ciąg, więc nie spowoduje błędu odniesienia. Dzieje się tak w innych miejscach, a także, weź to na przykład:

var a = function(){}; var b = function(){}; 
console.log(a + b); // `+` coerces with `toString` 

dlaczego:

szeregowanie funkcji w starych przeglądarek nie są wiarygodne i nie może wysyłać nieruchomość w organizmie danej funkcji _super , ale (zakładam) coś w rodzaju function{[native code]} lub [object Object]; w takich przypadkach należy użyć wyrażenia regularnego, takiego jak /.*/, aby dopasować dowolne elementy i nie wykonywać optymalizacji, które można wykonać w przeglądarkach, które dają prawidłowy wynik.

Powiązane linki do Więcej informacji:

http://blog.buymeasoda.com/understanding-john-resigs-simple-javascript-i/ (znaleziona przez Andreas)
http://es5.github.io/x15.3.html#x15.3.4.2
http://bytes.com/topic/javascript/answers/747203-function-tostring