Подтвердить что ты не робот

Как определить глобальные переменные в 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. Что означает "прикрепить их как свойства к окну"?

4b9b3361

Ответ 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