javascript - convertir - ¿Cómo defino variables globales en CoffeeScript?
js to coff (8)
A mí me parece que @atomicules tiene la respuesta más simple, pero creo que se puede simplificar un poco más. this.anything
colocar una @
antes de cualquier cosa que desee que sea global, de modo que se this.anything
para esto. this.anything
y this
refiera al objeto global.
asi que...
@bawbag = (x, y) ->
z = (x * y)
bawbag(5, 10)
compila a ...
this.bawbag = function(x, y) {
var z;
return z = x * y;
};
bawbag(5, 10);
y trabaja dentro y fuera de la envoltura 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
En Coffeescript.org:
bawbag = (x, y) ->
z = (x * y)
bawbag(5, 10)
compilaría para:
var bawbag;
bawbag = function(x, y) {
var z;
return (z = (x * y));
};
bawbag(5, 10);
la compilación a través de coffee-script en node.js lo envuelve así:
(function() {
var bawbag;
bawbag = function(x, y) {
var z;
return (z = (x * y));
};
bawbag(5, 10);
}).call(this);
Los docs dicen:
Si desea crear variables de nivel superior para otras secuencias de comandos, adjúntelas como propiedades en la ventana o en el objeto de exportaciones en CommonJS. El operador existencial (que se describe a continuación) le brinda una manera confiable de averiguar dónde agregarlos, si está apuntando tanto a CommonJS como al navegador: root = exports? esta
¿Cómo defino las variables globales entonces en CoffeeScript. ¿Qué significa ''adjuntarlos como propiedades en la ventana''?
Creo que lo que estás tratando de lograr se puede hacer así:
Mientras está compilando el coffeescript, use el parámetro "-b".
-b
/ --bare
Compile el JavaScript sin la envoltura de seguridad de función de nivel superior.
Así que algo como esto: coffee -b --compile somefile.coffee whatever.js
Esto generará su código al igual que en el sitio CoffeeScript.org.
Dado que coffeescript rara vez se usa solo, puede usar global
variable global
proporcionada por node.js o browserify (y cualquier descendiente como coffeeify, gulp build scripts, etc.).
En node.js global
es el espacio de nombres global.
En browserify global
es igual a la window
.
Por lo que sólo:
somefunc = ->
global.variable = 123
Ivo lo definió, pero mencionaré que hay un truco sucio que puede usar, aunque no lo recomiendo si busca puntos de estilo: puede incrustar código JavaScript directamente en su CoffeeScript evitándolo con backticks.
Sin embargo, aquí es por qué esto suele ser una mala idea: el compilador de CoffeeScript no es consciente de esas variables, lo que significa que no obedecerán las reglas normales de alcance de CoffeeScript. Asi que,
`foo = ''bar''`
foo = ''something else''
compila a
foo = ''bar'';
var foo = ''something else'';
y ahora te tienes a ti mismo dos foo
en diferentes ámbitos. No hay forma de modificar el foo
global desde el código de CoffeeScript sin hacer referencia al objeto global, como lo describió Ivy.
Por supuesto, esto es solo un problema si realiza una asignación a foo
en CoffeeScript; si foo
convirtió en de solo lectura después de recibir su valor inicial (es decir, es una constante global), entonces el enfoque de la solución de JavaScript incrustado podría ser bastante aceptable ( aunque todavía no se recomienda).
Para añadir a la respuesta de Ivo Wetzel.
Parece que hay una sintaxis abreviada para las exports ? this
exports ? this
que solo puedo encontrar documentado / mencionado en una publicación de grupo de Google .
Es decir, en una página web para que una función esté disponible globalmente, declare la función nuevamente con un prefijo @
:
<script type="text/coffeescript">
@aglobalfunction = aglobalfunction = () ->
alert "Hello!"
</script>
<a href="javascript:aglobalfunction()" >Click me!</a>
Puede pasar la opción -b al compilar código a través de coffee-script en node.js. El código compilado será el mismo que en coffeescript.org.
Si eres una mala persona (yo soy una mala persona), puedes ser tan simple como esto: (->@)()
Como en,
(->@)().im_a_terrible_programmer = yes
console.log im_a_terrible_programmer
Esto funciona, porque cuando se invoca una Reference
a una Function
''bare'' (es decir, func()
, en lugar de la new func()
u obj.func()
), algo que comúnmente se conoce como el ''patrón de invocación de llamada de función'', siempre se enlaza con el objeto global para ese contexto de ejecución .
El CoffeeScript anterior simplemente compila a (function(){ return this })()
; así que estamos ejercitando ese comportamiento para acceder de manera confiable al objeto global.
Ya que coffee script no tiene una declaración var
, automáticamente lo inserta para todas las variables en coffee-script, de esa manera evita que la versión compilada de JavaScript filtre todo en el espacio de nombres global .
Por lo tanto, dado que no hay manera de hacer que algo se filtre en el espacio de nombres global desde el punto de vista de las cosas del café a propósito, debe definir sus variables globales como propiedades del objeto global .
adjuntarlos como propiedades en la ventana
Esto significa que necesitas hacer algo como window.foo = ''baz'';
, que maneja el caso del navegador, ya que allí el objeto global es la window
.
Node.js
En Node.js no hay ningún objeto de window
, en su lugar está el objeto de exports
que se pasa al contenedor que envuelve el módulo Node.js (consulte: https://github.com/ry/node/blob/master/src/node.js#L321 ), así que en Node.js lo que necesitarías hacer es exports.foo = ''baz'';
.
Ahora echemos un vistazo a lo que dice en su cita de los documentos:
... dirigiéndose tanto a CommonJS como al navegador: root = exports? esta
Esto es obviamente un script de café, así que echemos un vistazo a lo que realmente compila:
var root;
root = (typeof exports !== "undefined" && exports !== null) ? exports : this;
Primero verificará si las exports
están definidas, ya que tratar de hacer referencia a una variable inexistente en JavaScript de otro modo produciría un SyntaxError (excepto cuando se usa con typeof
)
Entonces, si existen exports
, como es el caso en Node.js (o en un sitio web mal escrito ...), la raíz apuntará a las exports
, de lo contrario a this
. Entonces, ¿qué es this
?
(function() {...}).call(this);
El uso de .call
en una función vinculará this
dentro de la función al primer parámetro pasado, en el caso del navegador, this
sería ahora el objeto de la window
, en el caso de Node.js, sería el contexto global que también está disponible como objeto global
.
Pero como tiene la función require
en Node.js, no hay necesidad de asignar algo al objeto global
en Node.js, en lugar de eso, debe asignarlo al objeto exports
que la función require
devuelve.
Café-guión
Después de toda esa explicación, esto es lo que debes hacer:
root = exports ? this
root.foo = -> ''Hello World''
Esto declarará nuestra función foo
en el espacio de nombres global (sea lo que sea).
Eso es todo :)