2

RubyRoguesポッドキャストの誰かがかつて「CoffeeScriptはあなたよりも優れたJavaScriptを書くので、CoffeeScriptを学ぶ」と言っていました。申し訳ありませんが、誰が言ったか思い出せません...

だから、私は非常に単純なWORKINGjavascript関数を取りました:

togglingii.js

function pdtogglejs(id) {   $('div .partybackground').removeClass("hidden");  }

これはこの行によって呼び出されています:

<a href="#" class="dctoggle" onclick="pdtogglejs('partybackground')">Read More...</a>

それから私はそれをこのコーヒースクリプトに変換しました: toggling.js.coffee

pdtogglecs(id) ->
   jQuery('div .partybackground').removeClass("hidden")

そして、pdtoggle * j * sではなくpdtoggle* c *sを参照するようにhtmlを変更しました。

私のapplication.jsファイルでは、両方とも問題なく表示されます。

(function() {

  pdtogglecs(id)(function() {
    return jQuery('div .partybackground').removeClass("hidden");
  });

}).call(this);
function pdtogglejs(id) {   $('div .partybackground').removeClass("hidden");  }
;
(function() {



}).call(this);

ただし、機能するのは純粋なJavaScriptのみです。Coffeescriptは常にUncaughtReferenceErrorを返します:pdtogglecsは定義されていません。

他のstackoverflowの質問に基づくと、それはある種の名前空間エラーであるに違いありません。おそらく、pdtogglecs自体が関数内にあるためか?ただし、window.pdtogglecs、this.pdtogglecs、root.pdtogglecsを使用してcoffeescript関数を定義しようとしましたが、coffescriptは常にそのエラーで失敗します。

何が足りないの?

ありがとう!!

4

1 に答える 1

11

2 つの問題があります。1 つは CoffeeScript 構文の混乱であり、もう 1 つはあなたが知っている名前空間の問題です。

構文の混乱を整理することから始めます。これ:

f(x) -> ...

は次のように解釈されます。

f(x)(-> ...)

したがって、これが与えられると:

pdtogglecs(id) ->
   jQuery('div .partybackground').removeClass("hidden")

CoffeeScript は、引数としてpdtogglecs関数として呼び出そうとしていると考えます。id次に、それが関数を返し、関数を引数としてpdtogglecs(id)その関数を呼び出したいと考えます。-> jQuery(...)したがって、次のようになります。

callback = -> jQuery(...)
returned_function = pdtogglecs(id)
returned_function(callback)

これは元の JavaScript とはまったく異なります。pdtogglecs引数として受け取りid、jQuery を実行するという名前の関数を作成します。

pdtogglecs = (id) ->
    # -----^ this is sort of important
    jQuery('div .partybackground').removeClass("hidden")

生成された JavaScript を見ると、何が起こっているかがわかります。

名前空間の問題は簡単で、見つけた他の質問に基づいておそらく理解できるでしょう。ただし、完全を期すためにここで処理します。

CoffeeScript は、各.coffeeファイルを自己実行関数でラップして、グローバル名前空間の汚染を回避します。

(function() {
    // JavaScript version of your CoffeeScript goes here...
})();

そのラッパーは、すべてを.coffeeファイルにスコープします。グローバル名前空間を汚染したい場合は、次のように言わなければなりません:

window.pdtogglecs = (id) -> ...

次のように言うこともできます。

@pdtogglecs = (id) -> ...

しかし、私は を直接参照する明示性を好みます。これにより、コードが解析されているときに(AKA ) がwindow何であるかを心配する必要もなくなります。@this

于 2012-11-14T21:34:47.080 に答える