Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
365 views
in Technique[技术] by (71.8m points)

javascript - How do I define global variables in CoffeeScript?

On 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:

(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

How do I define Global Variables then in CoffeeScript. What does 'attach them as properties on window' mean?

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.

So since there's no way to make something "leak" into the global namespace from the coffee-script side of things on purpose, you need to define your global variables as properties of the 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 object is the window.

Node.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';.

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

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)

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?

(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 context which is also available as the global object.

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.

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 :)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...