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);
compilando a través de coffee-script en node.js envuelve eso:
(function() {
var bawbag;
bawbag = function(x, y) {
var z;
return (z = (x * y));
};
bawbag(5, 10);
}).call(this);
Los documentos dicen:
Si desea crear variables de nivel superior para que otras secuencias de comandos las utilicen, adjúntelas como propiedades en la ventana o en el objeto de exportaciones en CommonJS. El operador existencial (cubierto a continuación), le brinda una forma confiable de averiguar dónde agregarlos, si está apuntando tanto a CommonJS como al navegador: raíz = exportaciones? esta
¿Cómo defino las variables globales en CoffeeScript? ¿Qué significa 'adjuntarlos como propiedades en la ventana'?
javascript
coffeescript
Tejedor manual
fuente
fuente
window
objeto o elexports
objeto. No es necesario crear variables globales.window
(oglobal
en nodejs)Respuestas:
Dado que la secuencia de comandos de café no tiene ninguna
var
declaración, la inserta automáticamente para todas las variables en la secuencia de comandos de café, de esa manera evita que la versión compilada de JavaScript filtre todo en el espacio de nombres global .Entonces, dado que no hay forma de hacer que algo "se filtre" en el espacio de nombres global desde el lado del script de café de las cosas a propósito, debe definir sus variables globales como propiedades del objeto global .
Esto significa que debe hacer algo como
window.foo = 'baz';
manejar el caso del navegador, ya que allí el objeto global es elwindow
.Node.js
En Node.js no hay ningún
window
objeto, en su lugar está elexports
objeto que se pasa al contenedor que envuelve el módulo Node.js (Ver: https://github.com/ry/node/blob/master/src/node.js# L321 ), entonces en Node.js lo que necesitarías hacer esexports.foo = 'baz';
.Ahora echemos un vistazo a lo que dice en su cita de los documentos:
Esto es obviamente un script de café, así que echemos un vistazo a lo que esto realmente compila:
Primero verificará si
exports
está definido, ya que intentar hacer referencia a una variable inexistente en JavaScript produciría un SyntaxError (excepto cuando se usa contypeof
)Entonces, si
exports
existe, que es el caso en Node.js (o en un sitio web mal escrito ...), la raíz apuntaráexports
, de lo contrario, athis
. Entonces que esthis
?El uso
.call
de una función vinculará elthis
interior de la función con el primer parámetro pasado, en el caso de que el navegadorthis
ahora sea elwindow
objeto, en el caso de Node.js sería el contexto global que también está disponible como elglobal
objeto.Pero dado que tiene la
require
función en Node.js, no es necesario asignar algo alglobal
objeto en Node.js, sino que asigna alexports
objeto que luego devuelve larequire
función.Coffee-Script
Después de toda esa explicación, esto es lo que debe hacer:
Esto declarará nuestra función
foo
en el espacio de nombres global (sea lo que sea).Eso es todo :)
fuente
global
,GLOBAL
yroot
los objetos en Node.js?ReferenceError
?(exports ? this).foo = -> 'Hello World'
global = exports ? this
. La afirmación de que "en el caso de Node.js sería el contexto global ..." es incorrecta porque lathis
variable, cuando es requerida o ejecutada por node.js, se evalúa como el alcance del módulo. Entonces, si espera establecer accesorios para que sea accesible a nivel mundial, se sentirá decepcionado. Si desea establecer las cosas globalmente en el contexto de node.js, debe usar laglobal
variable, en lugar de hacerlothis
.Para mí, parece que @atomicules tiene la respuesta más simple, pero creo que se puede simplificar un poco más. Debe poner un
@
antes de cualquier cosa que quiera que sea global, para que se compilethis.anything
y hagathis
referencia al objeto global.entonces...
compila para ...
y funciona dentro y fuera del contenedor dado por node.js
fuente
this
ya no se refiere al objeto globalwindow.myVariable
cuál funcionará en cualquier lugar.=>
lugar de->
que instruya coffeescript para crear la función bajo el espacio de nombre this / globalIvo lo acertó, pero mencionaré que hay un truco sucio que puedes usar, aunque no lo recomiendo si buscas puntos de estilo: puedes incrustar código JavaScript directamente en tu CoffeeScript escapándolo con backticks.
Sin embargo, he aquí por qué suele ser una mala idea: el compilador de CoffeeScript desconoce esas variables, lo que significa que no obedecerán las reglas de alcance normales de CoffeeScript. Entonces,
compila a
y ahora tienes dos
foo
s en diferentes ámbitos. No hay forma de modificar el código globalfoo
de CoffeeScript sin hacer referencia al objeto global, como describió Ivy.Por supuesto, esto es solo un problema si realiza una asignación
foo
en CoffeeScript: si sefoo
convierte en 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 algo aceptable (aunque aún así no recomendado).fuente
foo
variable local , debido a lavar
elevación (JS escanea todas lasvar
declaraciones y las interpreta como si estuvieran en la parte superior de la función)expect = require('chai').expect;
marcasexpect
disponibles variable en todos mis archivos de prueba!Puede pasar la opción -b cuando compila código mediante coffee-script en node.js. El código compilado será el mismo que en coffeescript.org.
fuente
-b
/--bare
va directamente después delcoffee
comando.Para agregar a la respuesta de Ivo Wetzel
Parece que hay una sintaxis abreviada para
exports ? this
eso que solo puedo encontrar documentado / mencionado en una publicación grupal de Google .Es decir, en una página web para que una función esté disponible globalmente, declara la función nuevamente con un
@
prefijo:fuente
Creo que lo que estás tratando de lograr simplemente se puede hacer así:
Mientras compila el coffeescript, use el parámetro "-b".
-b
/--bare
Compile el JavaScript sin la función de seguridad de nivel superior.Entonces algo como esto:
coffee -b --compile somefile.coffee whatever.js
Esto generará su código al igual que en el sitio CoffeeScript.org.
fuente
Si eres una mala persona (yo soy una mala persona), puedes ser tan simple como esto:
(->@)()
Como en,
Esto funciona, porque cuando se invoca a
Reference
aFunction
'bare' (es decir, enfunc()
lugar denew func()
oobj.func()
), algo comúnmente conocido como 'patrón de invocación de llamada a función', siempre se unethis
al objeto global para ese contexto de ejecución .El CoffeeScript anterior simplemente se compila a
(function(){ return this })()
; entonces estamos ejerciendo ese comportamiento para acceder de manera confiable al objeto global.fuente
Dado que coffeescript rara vez se usa solo, puede usar la
global
variable proporcionada por node.js o browserify (y cualquier descendiente como coffeeify, scripts de compilación gulp, etc.).En node.js
global
hay un espacio de nombres global.En browserify
global
es igual awindow
.Por lo que sólo:
fuente