Jak zdefiniować zmienne globalne w CoffeeScript?
On Coffeescript.org:
bawbag = (x, y) ->
z = (x * y)
bawbag(5, 10)
Skompiluje się do:
var bawbag;
bawbag = function(x, y) {
var z;
return (z = (x * y));
};
bawbag(5, 10);
Kompilowanie przez coffee-script pod węzłem.js owija to tak:
(function() {
var bawbag;
bawbag = function(x, y) {
var z;
return (z = (x * y));
};
bawbag(5, 10);
}).call(this);
Docs says:
Jeśli chcesz utworzyć zmienne najwyższego poziomu dla innych skryptów, załączyć je jako właściwości w oknie lub na obiekcie exports w CommonJS. Operatorem egzystencjalnym (omówionym poniżej), daje niezawodny sposób, aby dowiedzieć się, gdzie je dodać, jeśli kierujesz oba CommonJS i przeglądarka: root = eksport ? this
Jak zdefiniować zmienne globalne w CoffeeScript. Co oznacza "załącz je jako właściwości w oknie"?
8 answers
Ponieważ skrypt coffee nie ma instrukcji var
, automatycznie wstawia ją dla wszystkich zmiennych w skrypcie coffee-script, dzięki czemu skompilowana wersja JavaScript nie wycieka wszystkiego doglobalnej przestrzeni nazw .
Więc ponieważ nie ma sposobu, aby coś "wyciekło" do globalnej przestrzeni nazw od strony skryptów kawowych celowo, musisz zdefiniować swoje zmienne globalne jako właściwości globalnego obiektu .
Dołącz je jako właściwości w oknie
Oznacza to, że musisz zrobić coś w rodzaju window.foo = 'baz';
, który obsługuje sprawę przeglądarki, ponieważ tam global object jest window
.
Węzeł.js
W Węźle.js nie ma window
obiektu, zamiast tego jest exports
obiekt, który jest przekazywany do owijarki, która owija węzeł.moduł js (Zobacz: https://github.com/ry/node/blob/master/src/node.js#L321 ), więc w węźle.js to co musisz zrobić to exports.foo = 'baz';
.
Teraz spójrzmy, co stwierdza w cytacie z dokumentów:
Jest to oczywiście skrypt kawowy, więc przyjrzyjmy się temu, do czego właściwie się składa:]}...targeting both CommonJS and the browser: root = exports ? to
var root;
root = (typeof exports !== "undefined" && exports !== null) ? exports : this;
Najpierw sprawdzi, czy exports
jest zdefiniowana, ponieważ próba odwołania się do nieistniejącej zmiennej w JavaScript w przeciwnym razie spowodowałaby błąd SyntaxError (z wyjątkiem sytuacji, gdy jest używany z typeof
)
Więc jeśli exports
istnieje, co ma miejsce w Node.js (lub w źle napisanej witrynie...) root będzie wskazywał na exports
, inaczej na this
. Więc co to jest this
?
(function() {...}).call(this);
Użycie .call
na funkcji spowoduje powiązanie this
wewnątrz funkcji z pierwszym przekazanym parametrem, w przypadku przeglądarki this
będzie teraz obiektem window
, W przypadku węzła.js będzie to kontekst globalny, który jest również dostępny jako obiekt global
.
Ale skoro masz require
funkcja w węźle.js, nie ma potrzeby przypisywania czegoś do global
obiektu w Node.js, zamiast tego przypisujesz obiekt exports
, który następnie jest zwracany przez funkcję require
.
Coffee-Script
Po tym wszystkim wyjaśnieniu, oto co musisz zrobić:
root = exports ? this
root.foo = -> 'Hello World'
To zadeklaruje naszą funkcję foo
w globalnej przestrzeni nazw (cokolwiek to się stanie).
To wszystko:)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-29 02:59:24
Wydaje mi się, że @atomicules ma najprostszą odpowiedź, ale myślę, że można ją nieco uprościć. Musisz umieścić @
przed wszystkim, co chcesz być globalne, tak, że kompiluje się do this.anything
i this
odnosi się do obiektu globalnego.
Więc...
@bawbag = (x, y) ->
z = (x * y)
bawbag(5, 10)
Kompiluje do...
this.bawbag = function(x, y) {
var z;
return z = x * y;
};
bawbag(5, 10);
I działa wewnątrz i na zewnątrz opakowania podanego przez node.js
(function() {
this.bawbag = function(x, y) {
var z;
return z = x * y;
};
console.log(bawbag(5,13)) // works here
}).call(this);
console.log(bawbag(5,11)) // works here
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-29 12:53:17
Ivo udało się, ale wspomnę, że jest jedna brudna sztuczka, której możesz użyć, choć nie polecam jej, jeśli chodzi o style points: możesz osadzać kod JavaScript bezpośrednio w CoffeeScript, uciekając go za pomocą backticks.
Jednakże, oto dlaczego jest to zazwyczaj zły pomysł: kompilator CoffeeScript nie jest świadomy tych zmiennych, co oznacza, że nie będą przestrzegać normalnych reguł coffeescript scoping rules. Więc
`foo = 'bar'`
foo = 'something else'
Kompiluje do
foo = 'bar';
var foo = 'something else';
And now you ' ve got yourself two foo
S w różnych zakresach. Nie ma możliwości modyfikacji globalnego foo
z kodu CoffeeScript bez odwoływania się do obiektu globalnego, jak opisano w Ivy.
Oczywiście, jest to tylko problem, jeśli przyporządkujesz foo
w CoffeeScript-jeśli foo
stało się tylko do odczytu po podaniu jej wartości początkowej( tzn. jest to stała globalna), to osadzone rozwiązanie JavaScript może być w pewnym sensie akceptowalne (choć nadal nie jest zalecane).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-20 05:07:17
Możesz przekazać opcję-b podczas kompilacji kodu przez coffee-script pod węzłem.js. Skompilowany kod będzie taki sam jak na coffeescript.org.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-27 06:49:15
Aby dodać do odpowiedź Ivo Wetzela
Wydaje się, że istnieje skrócona składnia exports ? this
, którą mogę znaleźć tylko udokumentowaną/wspomnianą na Google Group posting.
Tzn. na stronie internetowej, aby funkcja była dostępna globalnie, deklarujesz funkcję ponownie za pomocą prefiksu @
:
<script type="text/coffeescript">
@aglobalfunction = aglobalfunction = () ->
alert "Hello!"
</script>
<a href="javascript:aglobalfunction()" >Click me!</a>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:26
Myślę, że to, co próbujesz osiągnąć, można po prostu zrobić tak:
Podczas kompilacji coffeescript użyj parametru "- b".
-b
/ --bare
skompilować JavaScript bez najwyższego poziomu funkcji safety wrapper.
Więc coś takiego: coffee -b --compile somefile.coffee whatever.js
To wyświetli Twój kod tak jak w CoffeeScript.org miejscu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-14 16:16:56
Jeśli jesteś złą osobą (jestem złą osobą.), można uzyskać tak proste jak to: (->@)()
Jak w,
(->@)().im_a_terrible_programmer = yes
console.log im_a_terrible_programmer
Działa to, ponieważ gdy wywołujemy Reference
do Function
'nagie' (to znaczy func()
, zamiast new func()
lub obj.func()
), coś powszechnie określane jako 'wzorzec wywołania funkcji', zawsze wiąże this
z obiektem globalnym dla tego kontekstu wykonania .
Powyższy CoffeeScript po prostu kompiluje się do (function(){ return this })()
; więc ćwiczymy to zachowanie niezawodny dostęp do globalnego obiektu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-19 03:51:05
Ponieważ coffeescript jest rzadko używany samodzielnie, możesz użyć zmiennej global
dostarczanej przez dowolny węzeł.js lub browserify (i wszelkie potomkinie, takie jak coffeeify, gulp build scripts itp.).
W węźle.js global
jest globalną przestrzenią nazw.
W browserify {[1] } jest równe window
.
Więc, po prostu:
somefunc = ->
global.variable = 123
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-03 12:04:53