5

チームが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.jsHTMLファイルの上部にあるスクリプトタグに含めます。独自のスクリプトファイルをロードします。

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関数を使用することも無益でした。

4

2 に答える 2

3

このために、道場は を作成しましdojo.globalた。windowこれは、dojo がロードされたを指します (フレーム レイアウトに適しています)。

したがって、グローバル変数を次のように宣言します。

require([ "dojo/_base/kernel", ... ] , function(kernel) {
    kernel.global.globalVariable = 1;
    console.log('set')
})

dojo.addOnLoad(function() {console.log('get', globalVariable);});
于 2012-11-01T17:43:54.527 に答える
2

windowグローバル スコープはグローバルオブジェクトを介してアクセスできるためwindow.foo = 'bar'、グローバル変数を作成するのと同じですfoo。詳細はこちら: https://stackoverflow.com/a/4862268/168382

于 2012-10-31T11:13:14.480 に答える