1

JSのクロージャと可変スコープの概念を理解するのに苦労しています。styleData具体的には、クラス内の深くネストされた変数にアクセスしてから、そのクラスから作成されたオブジェクトにアクセスするにはどうすればよいですか?

ここには他にもいくつか間違っていることがあると思いますので、チャイムを鳴らして、適切と思われる場所で修正してください。ありがとう!

var BuildJSON = {
    convert: function() {
        $.ajax({
            type: "GET",
            url: "style2.xml",
            dataType: "xml",
            success: function(xml) {
                var styleData = $.xml2json(xml);
                return styleData; // Do I need to return this somehow?
            }
        //How to get access to styleData??
        });                 
    },

    styleData: this.convert();
};

var myClass = function() {
    this.info = BuildJSON.styleData;
};

var myObject = new myClass;

alert(myObject.info.Style[0].name);
4

2 に答える 2

3

JavaScriptのクロージャは関数であるため、関数スコープ内で宣言されたものはすべて、その関数内でのみ表示されます。

あなたの例styleDataはローカルであり、関数に属しており、success他の場所からはアクセスできません。最も簡単な解決策は、スコープの上部でその変数を宣言することBuildJSONです。この場合、そのオブジェクトをオブジェクトリテラルとして宣言しているため、そのオブジェクトのプロパティとして初期化できます。

this.styleData = '',

...

success: function(xml) {
  BuildJSON.styleData = $.xml2json(xml);
}

このアプローチの「問題」styleDataは公開されていることであり、おそらくそれはあなたが望んでいることではありません。BuildJSON内でその変数を使用したいが、公開してアクセス可能にしたくない場合は、モジュールパターンが役に立ちます。

var BuildJSON = (function(){
  var styleData = '', // local
      convert = function(){ ... } // You can use style data here

  return {
    convert: convert // Return only stuff you want to be public
  }
}())
于 2012-07-22T23:31:48.180 に答える
0

ここでの大きな問題は、AJAX呼び出しに対する非同期プログラミングの問題であり、コールバック自体の問題です。

できることの1つは、ajaxコールバックから明示的にstyleDataを設定することです。外部スコープの「that」変数にアクセスして、内部スコープから変更する方法に注意してください。

var BuildJSON = {
   convert: function() {
        var that  = this; // inner callbacks get separate "this" 
                          // variables so we save the BuildJSON in a separate variable.
        $.ajax({
            type: "GET",
            url: "style2.xml",
            dataType: "xml",
            success: function(xml) {
                that.styleData = $.xml2json(xml);
            }
        });                 
    }
};
BuildJSON.convert();

これは簡単に実行できますが、変換の実行が終了した後にのみ「styleData」プロパティを読み取ることができるという欠点があります。また、コードの記述方法では、ajax呼び出しが完了したことを知る方法がありません(他のポーリングsetintervalを使用したstyleData変数ですが、それはばかげています)。

非同期関数から内部値を「返す」には、主に2つの方法があります。1つの方法は、$。ajax自体と同じように、関数を継続渡しスタイルに変換することです。このように、styleDataの結果を返す代わりに、計算が完了したときにstyledataで呼び出す関数を受け取ります。

convert: function( onStyleData ) {
    $.ajax({
        // ...
        success: function(xml) {
            var styleData = $.xml2json(xml);
            onStyleData( styledata ); // <---
        }
    });                 
};

BuildJSON.convert(function(styledata){
    console.log('got styledata', styledata)
})

もう1つの可能性は、JQueryのpromiseサポートを利用することです。ajaxなどの関数は、非同期プログラミングをより便利にする特別なpromiseオブジェクトを返します(手動CPSを強制する代わりに、「return」を使用して値を返すコードを記述できるためです。

JQueryでこのために使用されている名前はよくわかりませんが、Dojoツールキットでは次のようになります。

var styleDataPromise = dojo.xhr({
    url: /*...*/,
    load: function(data){
       return xmlToJSON(xml);
    }
})

styleDataPromise.then(function(styleData){
    console.log('got styledata', styleData)
})
于 2012-07-22T23:44:19.230 に答える