Coffeescript.orgでは、
bawbag = (x, y) ->
z = (x * y)
bawbag(5, 10)
にコンパイルされます:
var bawbag;
bawbag = function(x, y) {
var z;
return (z = (x * y));
};
bawbag(5, 10);
node.jsの下でcoffee-scriptを介してコンパイルすると、次のようになります。
(function() {
var bawbag;
bawbag = function(x, y) {
var z;
return (z = (x * y));
};
bawbag(5, 10);
}).call(this);
ドキュメントは言う:
他のスクリプトが使用するトップレベルの変数を作成したい場合は、それらをウィンドウまたはCommonJSのexportsオブジェクトにプロパティとして添付します。 CommonJSとブラウザの両方をターゲットにしている場合、存在演算子(以下で説明)を使用すると、信頼できる方法でそれらを追加する場所を見つけることができます。この
その後、CoffeeScriptでグローバル変数を定義するにはどうすればいいですか。 「ウィンドウのプロパティとしてそれらを添付する」とはどういう意味ですか?
Coffeeスクリプトにはvar
name__ステートメントがないため、coffeeスクリプト内のすべての変数に自動的に挿入されます。これにより、コンパイルされたJavaScriptバージョンがglobal namespaceにすべてが漏れるのを防ぎます。
意図的にコーヒースクリプト側からglobal namespaceに何かを "リーク"させる方法はないので、あなたはglobal object]のプロパティとしてあなたのグローバル変数を定義する必要があります。。
ウィンドウ上のプロパティとしてそれらを添付してください
global objectがwindow
name__なので、ブラウザのケースを扱うwindow.foo = 'baz';
のようなことをする必要があります。
Node.jsにはwindow
name__オブジェクトはなく、代わりにNode.jsモジュールをラップするラッパーに渡されるexports
name__オブジェクトがあります(参照: https://github.com/ry/node/blob/master/) src/node.js#L321 )、Node.jsではexports.foo = 'baz';
を実行する必要があります。
それでは、ドキュメントから引用した内容を見てみましょう。
... CommonJSとブラウザの両方をターゲットにしています:root = exports?この
これは明らかにコーヒースクリプトなので、実際にコンパイルされる内容を見てみましょう。
var root;
root = (typeof exports !== "undefined" && exports !== null) ? exports : this;
最初にexports
name__が定義されているかどうかをチェックします。JavaScriptで存在しない変数を参照しようとすると、そうでなければSyntaxErrorが返されるためです(typeof
name__と一緒に使用する場合を除く)。
したがって、exports
name__が存在する場合、これはNode.js(または不適切に記述されたWebSite ...)の場合のように、rootはexports
name__を指し、それ以外の場合はthis
name__を指します。 this
name__とは何ですか?
(function() {...}).call(this);
関数で.call
を使用すると、関数内のthis
name__が最初に渡されたパラメータにバインドされます。ブラウザの場合はthis
name__がwindow
name__オブジェクトになり、Node.jsの場合はglobal contextこれはglobal
name__オブジェクトとしても利用可能です。
しかし、Node.jsにrequire
name__関数があるので、Node.jsのglobal
name__オブジェクトに何かを代入する必要はなく、代わりにexports
name__オブジェクトに代入します。このオブジェクトはrequire
name__関数によって返されます。
説明が終わったら、ここであなたがする必要があるものがあります。
root = exports ? this
root.foo = -> 'Hello World'
これはグローバルネームスペースで私たちの関数foo
name__を宣言します(それが何であれ)。
それで全部です :)
私には@atomiculesが最も単純な答えを持っているように見えますが、もう少し単純化できると思います。 @
にコンパイルしてthis
がグローバルオブジェクトを参照するように、グローバルにしたいものの前にthis.anything
を置く必要があります。
@bawbag = (x, y) ->
z = (x * y)
bawbag(5, 10)
this.bawbag = function(x, y) {
var z;
return z = x * y;
};
bawbag(5, 10);
(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
私はそれを釘付けにしました、しかし私はあなたが使うことができる1つの汚いトリックがあることに言及するでしょう、あなたがスタイルポイントのために行くなら私はそれをお勧めしません。
しかし、これが通常悪い考えである理由はここにあります:CoffeeScriptコンパイラはそれらの変数に気づいていません、それは彼らが通常のCoffeeScriptスコープ規則に従わないことを意味します。そう、
`foo = 'bar'`
foo = 'something else'
にコンパイル
foo = 'bar';
var foo = 'something else';
そして今、あなたは2つのfoo
を異なるスコープで持っています。 Ivyが述べたように、グローバルオブジェクトを参照せずにCoffeeScriptコードからglobalfoo
を変更する方法はありません。
もちろん、これはCoffeeScriptでfoo
に代入する場合にのみ問題になります。もし初期値が与えられた後にfoo
が読み取り専用になった場合(つまりグローバル定数である場合)、組み込みJavaScriptソリューションのアプローチはちょっと許容できるかもしれません。まだお勧めできませんが)。
Node.jsの下のcoffee-scriptでコードをコンパイルするときに-bオプションを渡すことができます。コンパイルされたコードはcoffeescript.orgと同じものになるでしょう。
私があなたが達成しようとしていることは、単純にこのようにすることができると思います:
コーヒースクリプトをコンパイルしている間は、 " - b"パラメータを使用します。
-b
/--bare
トップレベルの関数安全ラッパーなしでJavaScriptをコンパイルします。
だから、このようなもの:coffee -b --compile somefile.coffee whatever.js
これはCoffeeScript.orgサイトのようにあなたのコードを出力します。
exports ? this
には、 グーグルのグループ投稿 にしか書かれていない、または言及されているものを見つけることができるという省略形の構文があるようです。
すなわちWebページで関数をグローバルに利用できるようにするには、@
プレフィックスを使用して関数を再度宣言します。
<script type="text/coffeescript">
@aglobalfunction = aglobalfunction = () ->
alert "Hello!"
</script>
<a href="javascript:aglobalfunction()" >Click me!</a>
あなたが悪い人であれば(私は悪い人です。)、あなたはこれと同じくらい簡単になることができます:(->@)()
のように、
(->@)().im_a_terrible_programmer = yes
console.log im_a_terrible_programmer
これは、Reference
をFunction
'bare'(つまり、func()
またはnew func()
の代わりにobj.func()
)に呼び出すときに、一般に「関数呼び出し呼び出しパターン」と呼ばれるものが原因で機能します。 alwaysはそのためにthis
をグローバルオブジェクトにバインドします 実行コンテキスト 。
上記のCoffeeScriptは単に(function(){ return this })()
にコンパイルします。そのため、グローバルオブジェクトに確実にアクセスするためにその動作を実行しています。
Coffeescriptはそれ自身ではめったに使用されないので、node.jsまたはbrowserify(およびcoffeeify、gulpビルドスクリプトなどの任意の子孫)によって提供されるglobal
変数を使用できます。
Node.jsではglobal
はグローバル名前空間です。
Browserifyではglobal
はwindow
と同じです。
これだけ:
somefunc = ->
global.variable = 123