Javascript 如何在 CoffeeScript 中定义全局变量?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4214731/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I define global variables in CoffeeScript?
提问by Handloomweaver
On Coffeescript.org:
在 Coffeescript.org 上:
bawbag = (x, y) ->
z = (x * y)
bawbag(5, 10)
would compile to:
将编译为:
var bawbag;
bawbag = function(x, y) {
var z;
return (z = (x * y));
};
bawbag(5, 10);
compiling via coffee-script under node.js wraps that so:
通过 node.js 下的 coffee-script 进行编译,所以:
(function() {
var bawbag;
bawbag = function(x, y) {
var z;
return (z = (x * y));
};
bawbag(5, 10);
}).call(this);
Docs say:
文档说:
If you'd like to create top-level variables for other scripts to use, attach them as properties on window, or on the exports object in CommonJS. The existential operator (covered below), gives you a reliable way to figure out where to add them, if you're targeting both CommonJS and the browser: root = exports ? this
如果您想为其他脚本创建顶级变量以供使用,请将它们作为属性附加到窗口或 CommonJS 中的导出对象上。如果您同时针对 CommonJS 和浏览器,则存在运算符(如下所述)为您提供了一种可靠的方法来确定在哪里添加它们: root = exports ? 这个
How do I define Global Variables then in CoffeeScript. What does 'attach them as properties on window' mean?
我如何在 CoffeeScript 中定义全局变量。“将它们附加为窗口上的属性”是什么意思?
回答by Ivo Wetzel
Since coffee script has no var
statement it automatically inserts it for all variables in the coffee-script, that way it prevents the compiled JavaScript version from leaking everything into the global namespace.
由于咖啡脚本没有var
声明,它会自动为咖啡脚本中的所有变量插入它,这样它就可以防止编译的 JavaScript 版本将所有内容泄漏到全局命名空间中。
So since there's no way to make something "leak" into the global namespacefrom the coffee-script side of things on purpose, you need to define your global variables as properties of the global object.
因此,由于无法故意从咖啡脚本方面将某些内容“泄漏”到全局命名空间中,因此您需要将全局变量定义为global object 的属性。
attach them as properties on window
将它们作为属性附加到窗口上
This means you need to do something like window.foo = 'baz';
, which handles the browser case, since there the global objectis the window
.
这意味着你需要做一些类似的事情window.foo = 'baz';
,它处理浏览器的情况,因为全局对象是window
.
Node.js
节点.js
In Node.js there's no window
object, instead there's the exports
object that gets passed into the wrapper that wraps the Node.js module (See: https://github.com/ry/node/blob/master/src/node.js#L321), so in Node.js what you would need to do is exports.foo = 'baz';
.
在 Node.js 中没有window
对象,而是exports
传递到包装 Node.js 模块的包装器中的对象(参见:https: //github.com/ry/node/blob/master/src/node.js# L321),所以在 Node.js 中你需要做的是exports.foo = 'baz';
.
Now let us take a look at what it states in your quote from the docs:
现在让我们来看看它在您从文档中引用的内容:
...targeting both CommonJS and the browser: root = exports ? this
...同时针对 CommonJS 和浏览器: root =exports ?这个
This is obviously coffee-script, so let's take a look into what this actually compiles to:
这显然是咖啡脚本,所以让我们看看它实际编译成什么:
var root;
root = (typeof exports !== "undefined" && exports !== null) ? exports : this;
First it will check whether exports
is defined, since trying to reference a non existent variable in JavaScript would otherwise yield an SyntaxError (except when it's used with typeof
)
首先它会检查是否exports
已定义,因为尝试在 JavaScript 中引用一个不存在的变量会产生一个 SyntaxError(除非它与 一起使用typeof
)
So if exports
exists, which is the case in Node.js (or in a badly written WebSite...) root will point to exports
, otherwise to this
. So what's this
?
因此,如果exports
存在,在 Node.js 中(或在写得不好的网站...)中就是这种情况,root 将指向exports
,否则指向this
. 那是什么this
?
(function() {...}).call(this);
Using .call
on a function will bind the this
inside the function to the first parameter passed, in case of the browser this
would now be the window
object, in case of Node.js it would be the global contextwhich is also available as the global
object.
使用.call
上的功能将绑定this
功能里面第一个参数传递,在浏览器的情况下,this
现在会是window
对象,在Node.js的的情况下,这将是全球范围内它也可作为global
对象。
But since you have the require
function in Node.js, there's no need to assign something to the global
object in Node.js, instead you assign to the exports
object which then gets returned by the require
function.
但是由于您require
在 Node.js 中拥有该函数,因此无需为global
Node.js 中的对象分配任何内容,而是分配给该exports
对象然后由该require
函数返回。
Coffee-Script
咖啡脚本
After all that explanation, here's what you need to do:
在进行了所有这些解释之后,您需要执行以下操作:
root = exports ? this
root.foo = -> 'Hello World'
This will declare our function foo
in the global namespace (whatever that happens to be).
That's all :)
这将foo
在全局命名空间中声明我们的函数(无论发生什么)。
就这样 :)
回答by Billy Moon
To me it seems @atomicules has the simplest answer, but I think it can be simplified a little more. You need to put an @
before anything you want to be global, so that it compiles to this.anything
and this
refers to the global object.
对我来说,@atomicules 似乎有最简单的答案,但我认为它可以简化一点。你需要@
在任何你想成为全局的东西之前放一个,这样它就可以编译this.anything
并this
引用全局对象。
so...
所以...
@bawbag = (x, y) ->
z = (x * y)
bawbag(5, 10)
compiles to...
编译为...
this.bawbag = function(x, y) {
var z;
return z = x * y;
};
bawbag(5, 10);
and works inside and outside of the wrapper given by node.js
并在 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
回答by Trevor Burnham
Ivo nailed it, but I'll mention that there is one dirty trick you can use, though I don't recommend it if you're going for style points: You can embed JavaScript code directly in your CoffeeScript by escaping it with backticks.
Ivo 解决了这个问题,但我会提到你可以使用一个肮脏的技巧,但如果你想要风格点,我不推荐它:你可以通过用反引号转义来直接将 JavaScript 代码嵌入到你的 CoffeeScript 中。
However, here's why this is usually a bad idea: The CoffeeScript compiler is unaware of those variables, which means they won't obey normal CoffeeScript scoping rules. So,
然而,这就是为什么这通常是一个坏主意的原因:CoffeeScript 编译器不知道这些变量,这意味着它们不会遵守正常的 CoffeeScript 范围规则。所以,
`foo = 'bar'`
foo = 'something else'
compiles to
编译为
foo = 'bar';
var foo = 'something else';
and now you've got yourself two foo
s in different scopes. There's no way to modify the globalfoo
from CoffeeScript code without referencing the global object, as Ivy described.
现在你foo
在不同的范围内有两个s。有没有办法修改全球foo
从CoffeeScript的代码而不引用全局对象,如常春藤描述。
Of course, this is only a problem if you make an assignment to foo
in CoffeeScript—if foo
became read-only after being given its initial value (i.e. it's a global constant), then the embedded JavaScript solution approach might be kinda sorta acceptable (though still not recommended).
当然,这只是foo
在 CoffeeScript 中进行赋值时的问题——如果foo
在被赋予初始值(即它是一个全局常量)后变为只读,那么嵌入式 JavaScript 解决方案方法可能有点可接受(尽管仍然不建议)。
回答by phongnh
You can pass -b option when you compile code via coffee-script under node.js. The compiled code will be the same as on coffeescript.org.
在node.js 下通过coffee-script 编译代码时可以传递-b 选项。编译后的代码将与 coffeescript.org 上的相同。
回答by atomicules
To add to Ivo Wetzel's answer
There seems to be a shorthand syntax for exports ? this
that I can only find documented/mentioned on a Google group posting.
似乎有一种速记语法exports ? this
,我只能在Google 群组帖子中找到记录/提及。
I.e. in a web page to make a function available globally you declare the function again with an @
prefix:
即在网页中使函数全局可用,您再次使用@
前缀声明该函数:
<script type="text/coffeescript">
@aglobalfunction = aglobalfunction = () ->
alert "Hello!"
</script>
<a href="javascript:aglobalfunction()" >Click me!</a>
回答by Sankalp Singha
I think what you are trying to achieve can simply be done like this :
我认为您想要实现的目标可以简单地这样做:
While you are compiling the coffeescript, use the "-b" parameter.
在编译咖啡脚本时,请使用“-b”参数。
-b
/ --bare
Compile the JavaScript without the top-level function safety wrapper.
-b
/--bare
在没有顶级函数安全包装器的情况下编译 JavaScript。
So something like this : coffee -b --compile somefile.coffee whatever.js
所以像这样: coffee -b --compile somefile.coffee whatever.js
This will output your code just like in the CoffeeScript.org site.
这将输出您的代码,就像在 CoffeeScript.org 站点中一样。
回答by ELLIOTTCABLE
If you're a bad person (I'm a bad person.), you can get as simple as this: (->@)()
如果你是一个坏人(我是一个坏人。),你可以像这样简单: (->@)()
As in,
就像在,
(->@)().im_a_terrible_programmer = yes
console.log im_a_terrible_programmer
This works, because when invoking a Reference
to a Function
‘bare' (that is, func()
, instead of new func()
or obj.func()
), something commonly referred to as the ‘function-call invocation pattern', alwaysbinds this
to the global object for that execution context.
这是有效的,因为当调用 aReference
到Function
“裸”(即,func()
,而不是new func()
或obj.func()
)时,通常称为“函数调用调用模式”的东西总是绑定this
到该执行上下文的全局对象。
The CoffeeScript above simply compiles to (function(){ return this })()
; so we're exercising that behavior to reliably access the global object.
上面的 CoffeeScript 简单地编译为(function(){ return this })()
; 所以我们正在运用这种行为来可靠地访问全局对象。
回答by metalim
Since coffeescript is rarely used on it's own, you can use global
variable supplied by either node.js or browserify (and any descendants like coffeeify, gulp build scripts, etc).
由于 coffeescript 很少单独使用,因此您可以使用global
由 node.js 或 browserify 提供的变量(以及像 coffeeify、gulp 构建脚本等的任何后代)。
In node.js global
is global namespace.
在 node.js 中global
是全局命名空间。
In browserify global
is equal to window
.
在 browserifyglobal
中等于window
.
So, just:
所以就:
somefunc = ->
global.variable = 123