Como faço para definir variáveis globais em CoffeeScript?
-
26-09-2019 - |
Pergunta
No Coffeescript.org:
bawbag = (x, y) ->
z = (x * y)
bawbag(5, 10)
gostaria de compilar:
var bawbag;
bawbag = function(x, y) {
var z;
return (z = (x * y));
};
bawbag(5, 10);
compilando através de coffee-script em node.js que envolve assim:
(function() {
var bawbag;
bawbag = function(x, y) {
var z;
return (z = (x * y));
};
bawbag(5, 10);
}).call(this);
Docs dizer:
Se você gostaria de criar de nível superior de variáveis para outros scripts para usar, anexá-las como propriedades na janela, ou sobre as exportações do objeto em CommonJS.O operador existencial (abordado abaixo), dá-lhe um maneira confiável para descobrir onde para adicioná-los, se você estiver segmentando tanto CommonJS e o navegador:raiz = exportações ?este
Como faço para definir Variáveis Globais, em seguida, em CoffeeScript.O que significa "anexá-las como propriedades na janela' significa?
Solução
Uma vez que o café script não tem var
instrução insere automaticamente para todas as variáveis no café-script, de que maneira ele impede que o compilado em JavaScript versão do vazamento de tudo para a espaço de nomes global.
Então, já que não há nenhuma maneira de fazer algo "fuga" para o espaço de nomes global do coffee-script do lado do coisas de propósito, você precisará definir suas variáveis globais como propriedades do objeto global.
anexá-las como propriedades na janela
Isso significa que você precisa para fazer algo como window.foo = 'baz';
, que lida com o navegador de caso, uma vez que há a objeto global é o window
.
Node.js
No Node.js não há window
objeto, vez que há a exports
objeto que é passado para a embalagem que envolve o Node.js módulo (Consulte: https://github.com/ry/node/blob/master/src/node.js#L321 ), portanto, no Node.js o que você precisa fazer é exports.foo = 'baz';
.
Agora vamos dar uma olhada no que ela afirma em sua citação de documentos:
...visando tanto CommonJS e o navegador:raiz = exportações ?este
Esta é, obviamente, coffee-script, então vamos dar uma olhada no que este realmente compila para:
var root;
root = (typeof exports !== "undefined" && exports !== null) ? exports : this;
Primeiro verifique se exports
é definido, uma vez tentando fazer referência a um inexistente variável em JavaScript caso contrário, iria produzir um SyntaxError (exceto quando usado com typeof
)
Por isso, se exports
existe, que é o caso em Node.js (ou mal escritos Site...) raiz irá apontar para exports
, caso contrário, a this
.Então, o que é this
?
(function() {...}).call(this);
Usando .call
em uma função de vincular o this
dentro da função para o primeiro parâmetro passado, no caso do navegador this
agora seria o window
objeto, no caso de Node.js seria o contexto global que também está disponível como o global
objecto.
Mas já que você tem o require
função Node.js, não há necessidade de atribuir um valor para o global
objeto Node.js, ao invés de atribuir para o exports
objeto que, em seguida, devolvido pelo require
função.
Coffee-Script
Depois de toda essa explicação, aqui está o que você precisa fazer:
root = exports ? this
root.foo = -> 'Hello World'
Isto irá declarar a nossa função foo
no espaço de nomes global (o que quer que seja).
Isso é tudo :)
Outras dicas
A mim parece @atomicules tem a resposta mais simples, mas eu acho que ela pode ser simplificada um pouco mais.Você precisa colocar uma @
antes de qualquer coisa você quer ser global, de modo que compila para this.anything
e this
refere-se ao objeto global.
então...
@bawbag = (x, y) ->
z = (x * y)
bawbag(5, 10)
compila para...
this.bawbag = function(x, y) {
var z;
return z = x * y;
};
bawbag(5, 10);
e funciona dentro e fora do invólucro dada por 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 acertou em cheio, mas eu vou falar que não é um truque sujo que você pode usar, porém eu não recomendo se você estiver indo para pontos de estilo:Você pode inserir o código JavaScript diretamente na sua CoffeeScript por fugir com aspas invertidas.
No entanto, aqui, é porque este é geralmente uma má idéia:O CoffeeScript compilador ignora essas variáveis, o que significa que eles não obedecem normal CoffeeScript regras de escopo.Assim,
`foo = 'bar'`
foo = 'something else'
compila para
foo = 'bar';
var foo = 'something else';
e agora você tem dois foo
s em diferentes âmbitos.Não há nenhuma maneira para modificar o global foo
a partir de CoffeeScript código sem referenciar o objeto global, como Hera descrito.
Claro, isso só é um problema se você fizer uma atribuição para foo
em CoffeeScript—se foo
tornou-se ler somente depois de ser dado o seu valor inicial (i.e.é uma constante global) e, em seguida, o JavaScript incorporado abordagem de solução pode ser um bocado sorta aceitável (embora ainda não recomendável).
Você pode passar a opção-b quando você compilar o código através de coffee-script em node.js.O código compilado será o mesmo em coffeescript.org.
Adicionar à Ivo Wetzel resposta
Parece haver uma sintaxe abreviada para exports ? this
que só posso encontrar documentado/mencionado em um Grupo do Google postagem.
I. e.em uma página da web para fazer uma função disponível globalmente declarar a função novamente com um @
prefixo:
<script type="text/coffeescript">
@aglobalfunction = aglobalfunction = () ->
alert "Hello!"
</script>
<a href="javascript:aglobalfunction()" >Click me!</a>
Eu acho que o que você está tentando alcançar pode simplesmente ser feito assim :
Enquanto você estiver compilando o coffeescript, utilize o "-b" parâmetro.
-b
/ --bare
Compilar o JavaScript sem a função de nível superior de segurança wrapper.
Então, algo como isto : coffee -b --compile somefile.coffee whatever.js
Isto irá gerar o seu código, assim como no CoffeeScript.org o site.
Se você é uma pessoa ruim (eu sou uma pessoa má.), você pode obter tão simples como este: (->@)()
Como em,
(->@)().im_a_terrible_programmer = yes
console.log im_a_terrible_programmer
Isso funciona, porque quando a invocação de uma Reference
para um Function
'nua' (isto é, func()
, em vez de new func()
ou obj.func()
), algo comumente referido como a "função-chamada invocação padrão', sempre se liga this
para o objeto global para que contexto de execução.
O CoffeeScript acima simplesmente compila para (function(){ return this })()
;então, nós estamos exercitando-se que o comportamento confiável de acesso a objetos globais.
Desde coffeescript é raramente usado para isso, você pode usar global
variável fornecido node.js ou browserify (e descendentes como coffeeify, gole a construção de scripts, etc.).
No node.js global
é espaço de nomes global.
Em browserify global
é igual a window
.
Assim, basta:
somefunc = ->
global.variable = 123