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

windowobjeto o elexportsobjeto. No es necesario crear variables globales.window(oglobalen nodejs)Respuestas:
Dado que la secuencia de comandos de café no tiene ninguna
vardeclaració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
windowobjeto, en su lugar está elexportsobjeto 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
exportsestá definido, ya que intentar hacer referencia a una variable inexistente en JavaScript produciría un SyntaxError (excepto cuando se usa contypeof)Entonces, si
exportsexiste, 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
.callde una función vinculará elthisinterior de la función con el primer parámetro pasado, en el caso de que el navegadorthisahora sea elwindowobjeto, en el caso de Node.js sería el contexto global que también está disponible como elglobalobjeto.Pero dado que tiene la
requirefunción en Node.js, no es necesario asignar algo alglobalobjeto en Node.js, sino que asigna alexportsobjeto que luego devuelve larequirefunción.Coffee-Script
Después de toda esa explicación, esto es lo que debe hacer:
Esto declarará nuestra función
fooen el espacio de nombres global (sea lo que sea).Eso es todo :)
fuente
global,GLOBALyrootlos 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 lathisvariable, 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 laglobalvariable, 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.anythingy hagathisreferencia al objeto global.entonces...
compila para ...
y funciona dentro y fuera del contenedor dado por node.js
fuente
thisya no se refiere al objeto globalwindow.myVariablecuá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
foos en diferentes ámbitos. No hay forma de modificar el código globalfoode CoffeeScript sin hacer referencia al objeto global, como describió Ivy.Por supuesto, esto es solo un problema si realiza una asignación
fooen CoffeeScript: si sefooconvierte 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
foovariable local , debido a lavarelevación (JS escanea todas lasvardeclaraciones y las interpreta como si estuvieran en la parte superior de la función)expect = require('chai').expect;marcasexpectdisponibles 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/--bareva directamente después delcoffeecomando.Para agregar a la respuesta de Ivo Wetzel
Parece que hay una sintaxis abreviada para
exports ? thiseso 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/--bareCompile el JavaScript sin la función de seguridad de nivel superior.Entonces algo como esto:
coffee -b --compile somefile.coffee whatever.jsEsto 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
ReferenceaFunction'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 unethisal 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
globalvariable proporcionada por node.js o browserify (y cualquier descendiente como coffeeify, scripts de compilación gulp, etc.).En node.js
globalhay un espacio de nombres global.En browserify
globales igual awindow.Por lo que sólo:
fuente