Как я могу определить глобальные переменные в CoffeeScript?
-
26-09-2019 - |
Вопрос
На 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. Экзистенциальный оператор (накрытый ниже), дает вам надежный способ выяснить, где их добавить, если вы нацеливаете как Commentjs, так и браузера: root = Exports? это
Как я могу определить глобальные переменные, затем в CoffeeScript. Что означает «прикрепить их как свойства в окне»?
Решение
Поскольку кофе сценарий не имеет 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';
.
Теперь давайте посмотрим на то, что он говорил в вашей цитате из документов:
... нацеливание как Commonjs, так и браузера: root = exports? это
Это, очевидно, кофе-скрипт, поэтому давайте посмотрим, что это на самом деле компилирует:
var root;
root = (typeof exports !== "undefined" && exports !== null) ? exports : this;
Сначала это проверит, exports
определяется, поскольку попытка ссылаться на несуществующую переменную в JavaScript в противном случае приведет к синтаксису (за исключением случаев, когда он используется с typeof
)
Так что если exports
существует, в котором есть случай в Node.js (или на плохом письменном сайте ...) root укажет exports
, иначе к this
. Отказ И что this
?
(function() {...}).call(this);
С использованием .call
на функцию свяжутся this
Внутри функции к первому параметру пройдено, в случае браузера this
теперь будет window
объект, в случае node.js это было бы глобальный контекст который также доступен как global
объект.
Но так как у вас есть require
функция в Node.js нет необходимости что-то присвоить global
объект в Node.js, вместо этого вы назначаете exports
объект, который затем возвращается require
функция.
Кофе-скрипт
После всего этого объяснения вот что вам нужно сделать:
root = exports ? this
root.foo = -> 'Hello World'
Это объявит нашу функцию foo
в глобальном пространстве имен (все, что происходит, чтобы быть).
Это все :)
Другие советы
Для меня кажется, что @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
IVO прибил его, но я упомяну, что есть один грязный трюк, который вы можете использовать, хотя я не рекомендую его, если вы собираетесь в точках стиля: вы можете встроить код JavaScript прямо в CoffeeScript, убегая его с помощью Backticks.
Однако вот почему это обычно плохое представление: компилятор CoffeeScript не знает о тех переменных, что означает, что они не подчиняются нормальному CoffeeSript Scoping правила. Так,
`foo = 'bar'`
foo = 'something else'
компилирует
foo = 'bar';
var foo = 'something else';
и теперь у вас есть два foo
S в разных областях. Там нет способа изменить Глобальный foo
От кода CoffeeScript без ссылки на глобальный объект, как описано плюща.
Конечно, это только проблема, если вы делаете задание foo
в CoffeeScript - если foo
Стал только чтение, только после его первоначального значения (т.е. это глобальная константа), то встроенный подход к решению JavaScript может быть вроде приемлемо (хотя до сих пор не рекомендуется).
Вы можете пройти опцию -b при компиляции кода через Coffee-Script под Node.js. Скомпилированный код будет таким же, как на CoffeeScript.org.
Чтобы добавить в Ответ IVO WetZel
Кажется, есть краткий синтаксис для exports ? this
что я могу найти только документально / упоминаться на Google Group Posting..
То есть на веб-странице, чтобы сделать функцию доступной глобально, вы снова объявляете функцию с помощью @
приставка:
<script type="text/coffeescript">
@aglobalfunction = aglobalfunction = () ->
alert "Hello!"
</script>
<a href="javascript:aglobalfunction()" >Click me!</a>
Я думаю, что вы пытаетесь достичь, можно просто сделать так:
Хотя вы собираете CoffeeScript, используйте параметр «-B».
-b
/ --bare
Скомпилируйте JavaScript без функции безопасности верхнего уровня.
Так что-то вроде этого: coffee -b --compile somefile.coffee whatever.js
Это выводит ваш код так же, как в сайте CoffeeScript.org.
Если вы плохой человек (я плохой человек), вы можете получить так просто, как это: (->@)()
Как в,
(->@)().im_a_terrible_programmer = yes
console.log im_a_terrible_programmer
Это работает, потому что при вызове Reference
к А. Function
«Голый» (то есть func()
, вместо new func()
или obj.func()
), что-то обычно называют «шаблон вызова функции-вызова», всегда связываться this
к глобальному объекту для этого Контекст выполнения.
CoffeeScript выше просто компилирует (function(){ return this })()
; Таким образом, мы осуществляем это поведение, чтобы надежно получить доступ к глобальному объекту.
Поскольку CoffeeScript редко используется на своем собственном, вы можете использовать global
Переменная, поставляемой либо Node.js, либо в браузерификации (и любых потомков, таких как для кожуры, сценарии сборки Gultp, и т. Д.).
В Node.js. global
это глобальное пространство имен.
В брауристере global
равно window
.
Итак, только:
somefunc = ->
global.variable = 123