На Coffeescript.org:
bawbag = (x, y) ->
z = (x * y)
bawbag(5, 10)
будет компилировать в:
var bawbag;
bawbag = function(x, y) {
var z;
return (z = (x * y));
};
bawbag(5, 10);
компиляция с помощью coffee-script под node.js оборачивает это так:
(function() {
var bawbag;
bawbag = function(x, y) {
var z;
return (z = (x * y));
};
bawbag(5, 10);
}).call(this);
Документы говорят:
Если вы хотите создать переменные верхнего уровня для использования другими сценариями, прикрепите их как свойства к окну или к объекту экспорта в CommonJS. Экзистенциальный оператор (описанный ниже) дает вам надежный способ выяснить, куда их добавить, если вы ориентируетесь и на CommonJS, и на браузер: root = exports? этот
Как определить глобальные переменные тогда в CoffeeScript. Что означает «прикрепить их как свойства к окну»?
javascript
coffeescript
Handloomweaver
источник
источник
window
объект илиexports
объект. нет необходимости создавать глобальные переменные.window
(илиglobal
на nodejs)Ответы:
Поскольку у сценария кофе нет
var
операторов, он автоматически вставляет его для всех переменных в сценарии кофе, таким образом он предотвращает утечку скомпилированной версии JavaScript в глобальное пространство имен .Таким образом, поскольку нет никакого способа сделать что-то «просачивающимся» в глобальное пространство имен со стороны кофейных сценариев, вы должны определить свои глобальные переменные как свойства глобального объекта .
Это означает, что вам нужно сделать что-то вроде
window.foo = 'baz';
, что обрабатывает случай браузера, так как там глобальный объект являетсяwindow
.Node.js
В Node.js нет
window
объекта, вместо этого естьexports
объект, который передается в оболочку, которая обертывает модуль Node.js (см .: https://github.com/ry/node/blob/master/src/node.js# L321 ), поэтому в Node.js вам нужно сделать следующееexports.foo = 'baz';
.Теперь давайте посмотрим, что говорится в вашей цитате из документации:
Это, очевидно, сценарий кофе, так что давайте посмотрим, к чему это на самом деле компилируется:
Сначала он проверит,
exports
определено ли это, поскольку попытка ссылки на несуществующую переменную в JavaScript в противном случае приведет к ошибке SyntaxError (кроме случаев, когда она используется сtypeof
)Таким образом, если
exports
существует, что имеет место в корне Node.js (или в плохо написанном веб-сайте ...), на него будет указывать корень, вexports
противном случае - наthis
. Ну и чтоthis
?Использование
.call
функции on будет связыватьthis
внутреннюю функцию с первым передаваемым параметром, в случае, если браузерthis
теперь будетwindow
объектом, в случае Node.js это будет глобальный контекст, который также доступен какglobal
объект.Но поскольку у вас есть
require
функция в Node.js, нет необходимости назначать что-либоglobal
объекту в Node.js, вместо этого вы присваиваетеexports
объект, который затем возвращаетсяrequire
функцией.Кофе-Script
После всего этого объяснения вот что вам нужно сделать:
Это объявит нашу функцию
foo
в глобальном пространстве имен (что бы это ни было).Вот и все :)
источник
global
,GLOBAL
иroot
объектов в Node.js?ReferenceError
?(exports ? this).foo = -> 'Hello World'
global = exports ? this
. Утверждение, что «в случае Node.js это будет глобальный контекст ...» неверно, потому чтоthis
переменная, когда требуется или запускается node.js, оценивается как область действия модуля. Так что, если вы ожидаете, что установка реквизитов сделает его доступным во всем мире, вы будете разочарованы. Если вы хотите установить все глобально в контексте node.js, вам нужно использоватьglobal
переменную, а неthis
.Мне кажется, @atomicules имеет самый простой ответ, но я думаю, что его можно упростить немного больше. Вам нужно поставить
@
перед всем, что вы хотите быть глобальным, чтобы он компилировалсяthis.anything
иthis
ссылался на глобальный объект.так...
компилируется в ...
и работает внутри и снаружи оболочки, предоставленной node.js
источник
this
больше не ссылается на глобальный объектwindow.myVariable
какая из них будет работать где угодно.=>
вместо->
этого команду coffeescript для создания функции в пространстве имен this / globalIvo прибил его, но я упомяну, что есть один грязный трюк, который вы можете использовать, хотя я не рекомендую его, если вы собираетесь использовать стилевые точки: вы можете встраивать код JavaScript прямо в ваш CoffeeScript, избегая его с помощью обратных кавычек.
Однако, вот почему это обычно плохая идея: компилятор CoffeeScript не знает об этих переменных, что означает, что они не будут подчиняться нормальным правилам области действия CoffeeScript. Так,
компилируется в
и теперь у вас есть две
foo
пары в разных сферах. Как описал Айви , невозможно изменить глобальныйfoo
код CoffeeScript без ссылки на глобальный объект.Конечно, это проблема, только если вы сделаете присваивание
foo
в CoffeeScript - если оноfoo
стало доступным только для чтения после получения его начального значения (т. Е. Глобальной константы), тогда подход к встроенному решению JavaScript может быть своего рода приемлемым (хотя все же не рекомендуется).источник
foo
переменная из-заvar
подъема (JS просматривает всеvar
объявления вперед и интерпретирует их, как если бы они были в верхней части функции)expect = require('chai').expect;
маркуexpect
переменной доступны во всех моих тестовых файлах!Вы можете передать опцию -b, когда компилируете код с помощью coffee-script в файле node.js. Скомпилированный код будет таким же, как на coffeescript.org.
источник
-b
/--bare
идет сразу послеcoffee
команды.Добавить к ответу Иво Ветцеля
Кажется, существует сокращенный синтаксис,
exports ? this
который я могу найти только документированным / упомянутым в публикации группы Google .То есть на веб-странице, чтобы сделать функцию доступной глобально, вы снова объявляете функцию с
@
префиксом:источник
Я думаю, что вы пытаетесь достичь, можно просто сделать так:
Пока вы компилируете coffeescript, используйте параметр "-b".
-b
/--bare
Скомпилировать JavaScript без функции-оболочки безопасности верхнего уровня.Так что-то вроде этого:
coffee -b --compile somefile.coffee whatever.js
Это выведет ваш код так же, как на сайте CoffeeScript.org.
источник
Если вы плохой человек (я плохой человек), вы можете получить так просто:
(->@)()
Как в,
Это работает, потому что при вызове
Reference
кFunction
«голым» (то естьfunc()
, вместо того ,new func()
илиobj.func()
), что - то обычно называют «функцией вызова вызова шаблона», всегда связываетсяthis
с глобальным объектом для этого контекста исполнения .Приведенный выше CoffeeScript просто компилируется в
(function(){ return this })()
; поэтому мы используем это поведение для надежного доступа к глобальному объекту.источник
Поскольку coffeescript редко используется сам по себе, вы можете использовать
global
переменную, предоставляемую либо node.js, либо browserify (и любыми потомками, такими как coffeeify, сценарии сборки gulp и т. Д.).В node.js
global
есть глобальное пространство имен.В browserify
global
равноwindow
.Итак, просто:
источник