2016-08-18 5 views
0

私はC#でこれを行うとは思わないでしょうが、javascriptはより柔軟にアクセスできるように設計されています。JavaScriptをサードパーティのクロージャに追加する

は自分のコードでは、私は関数にwindow.beforeSend = function(d){}

を持っており、それは私が変更する必要がスコープ内にあるsomeDataがを持っているので、この

(function($) 
{ 
    ...more stuff 
    var results={a:1,b:2} //this I need to modify 
    var someData={x:1} 
    send = function(){ 
     //send results ajax 
    }; 

    if(typeof beforeSend=='function') 
     beforeSend(someData) //hook to use results 
})(jQuery) 

のようなプラグインがあります。しかしここに質問があります: どうすればいいですか結果 varは送信前にクロージャ内にあります。 私は

window.beforeSend = function(d){ 
    window.quantumTunnelThroughScope.results['c']=1 
} 

私はプラグインのコードを変更することはできませんので、これは実行する必要がある理由を追加する必要があります。もちろん、beforeSendをクロージャー内に追加すると、それは機能しますが、この場合は私が許可していないライブラリを変更しています。

私はいくつかの素晴らしいeval( 'this.xx' = function)などを見ましたが、動作させることはできません。

EDIT:私は実際にそれが

+0

グローバル変数:$(".foo").bar()bar、あなたはjQuery.fn代わりのjQuery上でそれを見つけることができますか? – mathiasfk

+0

@TJCrowderよく、結果を送る前にc = 1を追加する必要があります。 – AwokeKnowing

+0

@TJCrowderはい、申し訳ありませんが、コードを本質的に減らしていますが、例で間違った変数を渡してしまいました。 – AwokeKnowing

答えて

1

を編集する必要があり、同じスコープ内の別のVARだいいえ、beforeSendは、その閉鎖に達するとresultsを変更するための合理方法はありませんことを明らかにしました。提示されたコード内のresultsは、そのクロージャ内のコードに対して完全に非公開です。

から不合理方法resultsを変更することがevalを経由して、逆コンパイルおよびプラグインの機能を再コンパイルすることで行うことを試してみて、私たちをすることができますbeforeSend前に、関数の呼び出しを挿入します。

(function($) { 
 
    $.run = function() { 
 
    // You mentioned "ajax," so let's make this 
 
    // asynchronous 
 
    setTimeout(function() { 
 
     var results = { 
 
     a: 1, 
 
     b: 2 
 
     }; 
 
     var someData = { // Need to modify this 
 
     x: 1 
 
     }; 
 
     send = function() { 
 
     //send results ajax 
 
     }; 
 

 
     if (typeof beforeSend == 'function') { 
 
     beforeSend(someData); //hook to use results 
 
     } 
 

 
     console.log("in plugin, results = ", results); 
 
    }, 10); 
 
    }; 
 
})(jQuery) 
 

 
window.modifyResults = function(d) { 
 
    return ["new", "results"]; 
 
}; 
 
window.beforeSend = function(r) { 
 
    r.c = 1; 
 
}; 
 

 
jQuery.run = (function() { 
 
    // Function#toString, on nearly all browsers, returns the source 
 
    // code of he function (or something near to it) except on functions 
 
    // implemented in native code. We take that string and replace 
 
    // the "beforeSend(someData);" call with two calls, the first of 
 
    // which lets us modify the `results` variable. Then we use eval 
 
    // to turn that back into a function, and assign the result to 
 
    // where the plugin put its function originally. 
 
    return eval("(" + jQuery.run.toString().replace(
 
    "beforeSend(someData);", 
 
    "results = modifyResults(results); beforeSend(someData);" 
 
) + ")"); 
 
})(); 
 

 
jQuery.run();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
をそれは、元のスコープの外にそれを持ち上げると、それを再コンパイルして

しかし はまたは、プラグインが書かれている方法に応じて、動作しない場合があります私たちの機能更新の範囲はjQuery.runです。

私はプラグインを修正するヒットを望むと思います。 :-)


注:上記では、「静的」なjQuery関数を使用しました。置き換えようとしているプラ​​グインがインスタンスの機能を提供する場合、jQueryインスタンスで呼び出すことのできる種類。

jQuery.fn.pluginFunction = eval(...); 
+0

申し訳ありません"before"では、実際のsend関数の前に実行されるbeforeSendフックを参照しています。そのbeforeSendフックは実際にはクロージャのコード内にあり、送信前にすでに呼び出されているので、私自身のコードでは、そのフック関数にコードを変更するマジックスコープを置くと、送信前に実行されます – AwokeKnowing

+0

また、 jqueryオブジェクトをブラウズすればオブジェクトを見ることができるので、何とかコードにアクセスできるはずです。 – AwokeKnowing

+0

また、スコープ自体に関数を注入できたら、変数 – AwokeKnowing

関連する問題