チームがDojo1.8にアップグレードした後、プロジェクトで作業しているレガシースクリプトの一部が機能しなくなったことに気づきました。具体的には、彼らが作成したグローバル変数はもう作成されていませんでした。
調べてみると、Dojo1.8チームはグローバル変数に非常に反対していることがわかりました。実際には、ユーザーがrequireの最後に次のコードを使用してrequiredスクリプトでグローバル変数を作成することを物理的に不可能にすることに反対しました。
req.eval =
function(text, hint){
return eval_(text + "\r\n////@ sourceURL=" + hint);
};
var eval_ = new Function('return eval(arguments[0]);');
それは素晴らしいことですが、私が使用している古いコードは変更できないため、これを回避し、代わりにローカルコンテキストでevalを実行する方法を見つけようとしています。
幸いなことに、dojo.eval
古いバージョンのDojoからはまだ存在しており、それが私が望んでいることを実行します。そのため、関数にアクセスしreq.eval
て変更する必要があります。特定の場合return dojo.eval(...)
でも実行する必要があります。eval(...)
問題は、にアクセスする方法がわからないことreq
です。何が起こるかです:
dojo.js
HTMLファイルの上部にあるスクリプトタグに含めます。独自のスクリプトファイルをロードします。
dojo.require
私自身のファイルからアクセスできます。define
スクリプトファイルで次のように定義されています。
'dojo/_base/loader':function(){
define(["./kernel", "../has", "require", "module", "./json", "./lang", "./array"], function(dojo, has, require, thisModule, json, lang, array) {
それが重要かどうかはわかりません。とにかく、のスコープ内ではdojo.require
、と呼ばれるものを見ることができinjectModule
ますが、自分のファイルでは見ることができません。 injectModule
はローカル変数であるため、で表示することはできませんthis
。これは、ファイルの先頭にある無名関数で定義されています。
(function(){ ... injectModule = function(){} ... })();
関数内にはinjectModule
、次の行があります。
req.getText(url, legacyMode!=sync, xhrCallback);
これはに行きreq.eval
ます。だからinjectModule
見ることができますreq
。
どうしたらいいかわかりません。私の悪質なJavaScriptのトリックはどれも、このスコープのグリッドロックをナビゲートし始めるのに役立ちませんでした。injectModule
良いスタートは、を呼び出す私の外部スクリプトファイルからどのように見えるかを理解することdojo.require
です。ただし、無名関数で定義されたローカル変数であるため、「bind」では実行できませんでした。これも可能になるのでしょうか?
物事を少し簡単にするために、ここに要約があります:
ファイル1:
<script src="dojo.js"></script>
dojo.require(File 3);
console.log(globalVar);
ファイル2:
(function(){req.eval = unhelpful function})();
define(["require"], function(module){
dojo.require = function(x){req.eval(x)}
});
ファイル3:
globalVar = ...;
ファイル1と3を変更できますが、ファイル3には常にグローバル変数が必要です。ファイル2を変更できません。目標はreq.eval
、ファイル2をより良い機能に変更することです。
スコープの変更はファイル3がまだグローバル変数を表示できないことを意味するため、グローバル変数を以前に宣言しても機能しません。
スコープが間違っており、サーバー側でJSが縮小されているため、リフレクションと文字列の置換は機能しません。
スコープが見えないため、ファイル1のメソッドを上書きしても機能しません。
JavaScriptbind
関数を使用することも無益でした。