Как я могу определить глобальные переменные в CoffeeScript?

StackOverflow https://stackoverflow.com/questions/4214731

  •  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';

и теперь у вас есть два fooS в разных областях. Там нет способа изменить Глобальный 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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top