2

参照を変更するために電話したり申請したりすることに興味はありませんthis。私自身の興味のために、私はJavaScriptの別のrequireテクニックのアイデアで遊んでいます.

関数で toString と eval を使用するサンプル ソリューション (単なる概念実証) がありますが、これを行うためのより安全で効率的な方法があるかどうか疑問に思っています。

// Sample module libraries (would probably be in their own files)
someModules = { 
    testModule: {test: function(){console.log("test from someModule")}},
    anotherModule: { doStuff: function(){console.log("Doin stuffs!");}}
};

sampleRequire = function() {

    // Load the modules
    for (var i=arguments.length-2; i>=0; --i){

        // Create a local variable reference to the module
        eval ('var '+arguments[i]+' = someModules.'+arguments[i].toString());
    }

    // Redefine the programmer's function so that it has my local vars in its scope
    eval("var fn = "+arguments[arguments.length-1]);

    return fn;
}

// Main code...
sampleRequire( 'testModule', 'anotherModule',
    function(){ 
        testModule.test();
        anotherModule.doStuff();
    }
)();

編集:

Pointy は、これが main 関数のスコープを完全に破壊することになるという優れた点を指摘しましたが、これはしばしば受け入れられないものでした。理想的には、他のスコープ変数を壊すことなく、モジュール変数が関数のスコープに追加されるのを見たいと思います (モジュール名を除いて - プログラマーは 2 つのことに同じ名前を使用しないことを知っている必要があります)。これはおそらく不可能だと思いますが、それでもいくつかのアイデアを見たいと思っています.

もう 1 つの目標は、モジュールごとにメイン関数に引数を追加することなく、これを柔軟に行うことです。それ以外の場合は、CommonJS スタイルを使用して振り出しに戻ることになります (私はこれと戦おうとしているわけではありません。スコープに興味があるだけです!)。

4

3 に答える 3

1

私は「あなたはそれを間違っている」と言う傾向があります。宣言されていない変数を使用することは、可能であっても決して良い考えではありません。

モジュールをグローバルオブジェクトに書き込む別のハックがあります。ただし、これはmain関数から呼び出されるメソッドに副作用をもたらす可能性があります。

sampleRequire = function() {

    var cache = {};
    var moduleNames = [].slice.call(arguments);
    var fn = moduleNames.pop();

    return function () {
        var result, name, i;
        // export modules to global object
        for (i = 0; i < moduleNames.length; i++) {
            name = moduleNames[i];
            cache[name] = window[name]; // remember old values
            window[name] = someModules[name];
        }
        result = fn.apply(null, arguments);
        // restore original global stuff
        for (i = 0; i < moduleNames.length; i++) {
            name = moduleNames[i];
            window[name] = cache[name];
        }
        return result;
    };
}

with私はまた、基本的にあなたが望むもののために作られたキーワードでいくつかの魔法を試しました。evalただし、この場合は機能しないようです。

于 2012-04-06T08:46:38.797 に答える
0

あなたが求めていることを行う他の方法は考えられません。evalまた、これはthat is notの数少ない使用例の 1 つかもしれないと思います。ただし、モジュールはそのスコープに依存する可能性があり、これによりモジュールが壊れる可能性があることに注意してください。

于 2012-04-05T15:30:44.513 に答える
0

次のようなものはどうですか:

someModules = { 
  testModule: {test: function(){console.log("test from someModule")}},
  anotherModule: { doStuff: function(){console.log("Doin stuffs!");}}
};

function requireModules() {
  var all = [];
  for (var i = 0, l = arguments.length; i<l; i++) {
    all.push(someModules[i]);
  }
  return all;
}

(function(testModule,anotherModule){
  testModule.test();
  anotherModule.doStuff();
}).apply(null,requireModules('testModule','anotherModule'));
于 2012-04-05T15:32:11.970 に答える