Как определить глобальные переменные в CoffeeScript?
На 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);
компиляция через кофе 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. Что означает "прикрепить их как свойства к окну"?
Ответы
Ответ 1
Так как кофе script не имеет инструкции var
, он автоматически вставляет его для всех переменных в coffee- script, тем самым он предотвращает утечку компилируемой версии JavaScript в глобальное пространство имен .
Так как нет способа сделать что-то "утечка" в глобальном пространстве имен из кофейной части script специально, вам нужно определить ваши глобальные переменные как свойства глобальный объект.
присоединяйте их как свойства в окне
Это означает, что вам нужно сделать что-то вроде 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';
.
Теперь давайте посмотрим, что он укажет в вашей цитате из документов:
... предназначенный как для CommonJS, так и для браузера: root = exports? это
Это, очевидно, coffee- script, поэтому давайте посмотрим, что это на самом деле компилирует:
var root;
root = (typeof exports !== "undefined" && exports !== null) ? exports : this;
Сначала он будет проверять, определен ли exports
, поскольку попытка ссылаться на несуществующую переменную в JavaScript в противном случае дает SyntaxError (кроме случаев, когда она используется с typeof
)
Итак, если exports
существует, что имеет место в Node.js(или в плохо написанном WebSite...), root будет указывать на exports
, в противном случае - на this
. Итак, что this
?
(function() {...}).call(this);
Использование .call
для функции свяжет this
внутри функции с первым переданным параметром, в случае браузера this
теперь будет объектом window
, в случае Node.js это будет глобальный контекст, который также доступен как объект global
.
Но поскольку у вас есть функция require
в Node.js, нет необходимости назначать что-то объекту global
в Node.js, вместо этого вы назначаете объект exports
, который затем получает возвращенный функцией require
.
Кофе- Script
После всего этого объяснения, вот что вам нужно сделать:
root = exports ? this
root.foo = -> 'Hello World'
Это объявит нашу функцию foo
в глобальном пространстве имен (что бы это ни случилось).
Что все:)
Ответ 2
Мне кажется, что @atomicules имеет самый простой ответ, но я думаю, что его можно упростить еще немного. Вам нужно поставить @
до того, что вы хотите быть глобальным, так что он компилируется в this.anything
и this
, ссылается на глобальный объект.
так...
@bawbag = (x, y) ->
z = (x * y)
bawbag(5, 10)
компилируется в...
this.bawbag = function(x, y) {
var z;
return z = x * y;
};
bawbag(5, 10);
и работает внутри и снаружи обертки, заданной 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
Ответ 3
Иво прибил его, но я упомянул, что есть один грязный трюк, который вы можете использовать, хотя я не рекомендую его, если вы собираетесь использовать точки стиля. Вы можете вставлять код JavaScript прямо в свой CoffeeScript, избегая его с backticks.
Однако здесь почему это обычно плохой идеал: компилятор CoffeeScript не знает этих переменных, а это значит, что они не будут подчиняться нормальным правилам обзора CoffeeScript. Таким образом,
`foo = 'bar'`
foo = 'something else'
компилируется в
foo = 'bar';
var foo = 'something else';
и теперь у вас есть два foo
в разных областях. Нет способа изменить глобальный foo
код CoffeeScript без ссылки на глобальный объект, как описано Ivy.
Конечно, это только проблема, если вы выполняете присвоение foo
в CoffeeScript - если foo
стал доступен только для чтения после того, как ему было задано его начальное значение (т.е. это глобальная константа), тогда встроенное решение для JavaScript подход может быть своего рода приемлемым (хотя все еще не рекомендуется).
Ответ 4
Вы можете передать параметр -b при компиляции кода через кофе script под node.js.
Скомпилированный код будет таким же, как на coffeescript.org.
Ответ 5
Чтобы добавить к ответ Иво Ветцеля
Кажется, что для exports ? this
есть сокращенный синтаксис, который я могу найти только в документах/упоминаниях в публикация группы Google.
т.е. на веб-странице, чтобы сделать доступную функцию глобально, вы снова объявляете функцию с префиксом @
:
<script type="text/coffeescript">
@aglobalfunction = aglobalfunction = () ->
alert "Hello!"
</script>
<a href="javascript:aglobalfunction()" >Click me!</a>
Ответ 6
Я думаю, что то, что вы пытаетесь достичь, можно просто сделать следующим образом:
Пока вы компилируете файл coffeescript, используйте параметр "-b".
-b
/--bare
Скомпилируйте JavaScript без защитной оболочки функции верхнего уровня.
Так что-то вроде этого: coffee -b --compile somefile.coffee whatever.js
Это выводит ваш код так же, как на сайте CoffeeScript.org.
Ответ 7
Если вы плохой человек (я плохой человек), вы можете сделать это просто: (->@)()
Как и в,
(->@)().im_a_terrible_programmer = yes
console.log im_a_terrible_programmer
Это работает, потому что при вызове Reference
в Function
'голый (то есть func()
вместо new func()
или obj.func()
) что-то обычно называется вызовом функции-вызова pattern всегда привязывает this
к глобальному объекту для контекста выполнения.
The CoffeeScript выше просто компилируется в (function(){ return this })()
; поэтому мы осуществляем это поведение для надежного доступа к глобальному объекту.
Ответ 8
Так как coffeescript редко используется на нем, вы можете использовать переменную global
, предоставленную либо node.js, либо прокручивать (и любые потомки, такие как coffeeify, gulp build scripts и т.д.).
В node.js global
- глобальное пространство имен.
В браузере global
равно window
.
Итак, просто:
somefunc = ->
global.variable = 123