Na Coffeescript.org:
bawbag = (x, y) ->
z = (x * y)
bawbag(5, 10)
skompilowałby się w:
var bawbag;
bawbag = function(x, y) {
var z;
return (z = (x * y));
};
bawbag(5, 10);
kompilacja za pomocą skryptu kawy pod opakowaniami node.js, które:
(function() {
var bawbag;
bawbag = function(x, y) {
var z;
return (z = (x * y));
};
bawbag(5, 10);
}).call(this);
Dokumenty mówią:
Jeśli chcesz utworzyć zmienne najwyższego poziomu do użycia dla innych skryptów, dołącz je jako właściwości w oknie lub w obiekcie eksportu w CommonJS. Operator egzystencjalny (omówiony poniżej) daje niezawodny sposób, aby dowiedzieć się, gdzie je dodać, jeśli celujesz zarówno w CommonJS, jak i przeglądarkę: root = eksportuje? to
Jak zdefiniować zmienne globalne w CoffeeScript. Co oznacza „dołącz je jako właściwości do okna”?
javascript
coffeescript
Handloomweaver
źródło
źródło
window
obiekt lubexports
obiekt. nie ma potrzeby tworzenia zmiennych globalnych.window
(lubglobal
nodejs)Odpowiedzi:
Ponieważ skrypt kawy nie ma
var
instrukcji, automatycznie wstawia ją do wszystkich zmiennych w skrypcie kawy, w ten sposób zapobiega wyciekaniu skompilowanej wersji JavaScript do globalnej przestrzeni nazw .Ponieważ więc nie ma sposobu, aby coś „wyciekło” do globalnej przestrzeni nazw od strony skryptów kawy celowo, musisz zdefiniować swoje zmienne globalne jako właściwości obiektu globalnego .
Oznacza to, że trzeba zrobić coś podobnego
window.foo = 'baz';
, który obsługuje sprawy przeglądarki, ponieważ tam globalny obiekt jestwindow
.Node.js
W Node.js nie ma
window
obiektu, zamiast tego jestexports
obiekt przekazywany do opakowania, które otacza moduł Node.js (patrz: https://github.com/ry/node/blob/master/src/node.js# L321 ), więc w Node.js musisz zrobićexports.foo = 'baz';
.Teraz rzućmy okiem na to, co mówi w cytacie z dokumentów:
Jest to oczywiście skrypt do kawy, więc przyjrzyjmy się temu, co to właściwie kompiluje:
Najpierw sprawdzi, czy
exports
jest zdefiniowany, ponieważ próba odwołania się do nieistniejącej zmiennej w JavaScript dałaby w przeciwnym razie błąd SyntaxError (z wyjątkiem sytuacji, gdy jest używana ztypeof
)Więc jeśli
exports
istnieje, co ma miejsce w Node.js (lub w źle napisanej witrynie WebSite ...), root wskażeexports
, w przeciwnym raziethis
. Co to jestthis
?Użycie
.call
na funkcji spowoduje powiązaniethis
wnętrza funkcji z pierwszym przekazanym parametrem, w przypadku przeglądarkithis
będzie terazwindow
obiektem, w przypadku Node.js globalnym kontekstem, który jest również dostępny jakoglobal
obiekt.Ale ponieważ masz
require
funkcję w Node.js, nie ma potrzeby przypisywania czegoś doglobal
obiektu w Node.js, zamiast tego przypisujeszexports
obiekt, który następnie jest zwracany przezrequire
funkcję.Kawa-skrypt
Po tych wszystkich wyjaśnieniach oto, co musisz zrobić:
Spowoduje to zadeklarowanie naszej funkcji
foo
w globalnej przestrzeni nazw (cokolwiek się stanie).To wszystko :)
źródło
global
,GLOBAL
iroot
obiektów w node.js?ReferenceError
?(exports ? this).foo = -> 'Hello World'
global = exports ? this
. Twierdzenie, że „w przypadku Node.js byłby to kontekst globalny ...” jest błędne, ponieważthis
zmienna, gdy jest wymagana lub uruchamiana przez node.js, jest oceniana jako zakres modułu. Więc jeśli spodziewasz się, że ustawienie rekwizytów sprawi, że będzie on dostępny na całym świecie, będziesz rozczarowany. Jeśli chcesz ustawić rzeczy globalnie w kontekście node.js, musiszglobal
zamiast tego użyć zmiennejthis
.Wydaje mi się, że @atomicules ma najprostszą odpowiedź, ale myślę, że można ją trochę uprościć. Musisz postawić
@
przed wszystkim, co chcesz być globalne, aby kompilowało sięthis.anything
ithis
odnosiło do obiektu globalnego.więc...
kompiluje się do ...
i działa wewnątrz i na zewnątrz opakowania podanego przez node.js
źródło
this
nie odnosi się już do obiektu globalnegowindow.myVariable
która będzie działać w dowolnym miejscu.=>
zamiast tego->
, instruuje coffeescript, aby utworzyć funkcję w tej / globalnej przestrzeni nazwIvo go przybił, ale wspomnę, że jest jedna brudna sztuczka, której można użyć, chociaż nie polecam jej, jeśli chcesz zdobyć punkty stylu: możesz osadzić kod JavaScript bezpośrednio w CoffeeScript, unikając go za pomocą backsticks.
Oto dlaczego jest to zwykle zły pomysł: kompilator CoffeeScript nie zna tych zmiennych, co oznacza, że nie będą przestrzegać normalnych zasad określania zakresu CoffeeScript. Więc,
kompiluje się do
a teraz masz dwie
foo
s w różnych zakresach. Nie ma sposobu, aby zmodyfikować kod globalnyfoo
z kodu CoffeeScript bez odwoływania się do obiektu globalnego, jak opisano w Ivy.Oczywiście jest to problem tylko wtedy, gdy wykonasz zadanie
foo
w CoffeeScript - jeśli stałoby się tylko dofoo
odczytu po otrzymaniu jego początkowej wartości (tj. Jest stałą globalną), wówczas podejście do osadzonego rozwiązania JavaScript może być trochę akceptowalne (choć nadal Niepolecane).źródło
foo
zmienna lokalna z powoduvar
podnoszenia (JS skanuje wszystkievar
deklaracje i interpretuje je tak, jakby znajdowały się na szczycie funkcji)expect = require('chai').expect;
czyniexpect
zmienną dostępną we wszystkich moich plikach testowych!Możesz przekazać opcję -b podczas kompilowania kodu za pomocą skryptu do kawy w pliku node.js. Skompilowany kod będzie taki sam jak na coffeescript.org.
źródło
-b
/--bare
idzie bezpośrednio pocoffee
poleceniu.Aby dodać do odpowiedzi Ivo Wetzela
Wydaje się, że istnieje skrócona składnia
exports ? this
, którą mogę znaleźć tylko w dokumentach grupy Google .Tj. Na stronie internetowej, aby udostępnić funkcję globalnie, deklarujesz ją ponownie z
@
prefiksem:źródło
Myślę, że to, co próbujesz osiągnąć, można po prostu zrobić w następujący sposób:
Podczas kompilowania skryptu coffeescript użyj parametru „-b”.
-b
/--bare
Skompiluj JavaScript bez opakowania bezpieczeństwa funkcji najwyższego poziomu.Więc coś takiego:
coffee -b --compile somefile.coffee whatever.js
Spowoduje to wygenerowanie kodu tak jak w witrynie CoffeeScript.org.
źródło
Jeśli jesteś złym człowiekiem (ja jestem złym człowiekiem), możesz uzyskać tak proste:
(->@)()
Jak w,
To działa, ponieważ kiedy Wywoływanie
Reference
DoFunction
„gołe” (czylifunc()
zamiastnew func()
lubobj.func()
), coś powszechnie określane jako „funkcja wywołania wywołania wzór”, zawsze wiążethis
do globalnego obiektu dla tego kontekstu wykonania .Powyższy CoffeeScript po prostu się kompiluje
(function(){ return this })()
; dlatego ćwiczymy to zachowanie, aby niezawodnie uzyskać dostęp do obiektu globalnego.źródło
Ponieważ coffeescript jest rzadko używany samodzielnie, możesz użyć
global
zmiennej dostarczonej przez node.js lub browserify (i dowolnych potomków, takich jak coffeeify, skrypty budowania gula itp.).W node.js
global
znajduje się globalna przestrzeń nazw.W Browserify
global
jest równywindow
.Więc tylko:
źródło