2013-03-16 10 views
10

グローバルオブジェクトを使用することはお勧めできません。また、AMDの背後にある考え方は、グローバルオブジェクトの使用を避けることです。しかし、いくつかのレガシーコードでは、グローバルオブジェクトにいくつかのものを定義する必要があります。現在のコードは次のようになります。requirejsを使用してグローバルオブジェクトにアクセスする

//example2.js 
define(function(){ 
    var globalObject = window; 
    globalObject.x = ... 
    globalObject.y = ... 
}); 

それはグローバルオブジェクトwindowをコーディングすることは非常に良い見て、私はそれを除去することが可能であるかどうかを確認するには興味がありませんが、一生懸命働いて。 define()が使用されなかった場合は、コードはこのように見えた:私は知っている

//example1.js 
x = ... 
y = ... 

、私はあなたがこのコードを嫌い知っているが、のがポイントになりましょう:どのようにグローバル変数をdefine()内の構造化された方法でアクセスすることができますrequirejsの関数ですか?

//example3.js 
define(function(globalObject){ 
    globalObject.x = ... 
    globalObject.y = ... 
}); 

それとももっと簡単:私はこのようなdefine()に渡される関数に隠された最後のパラメータのようなものがあったことを望むthis変数は、その関数内のグローバルオブジェクトを指します。

//example4.js 
define(function(){ 
    this.x = ... 
    this.y = ... 
}); 

注:たとえば私はこの最後のものについてはよく分かりません。 require()に渡される関数内でthis変数を調べると、それはwindowと同じですが、これは私の質問に対する答えになりますが、渡された関数が実行されていることを示す文章を見つけることができませんでした。結局のところ、グローバル変数のコンテキストで実行されているのでしょうか?あなたがstrictモードでない場合は

答えて

5

、あなたはこれを行うことができます。

(function() { 
    var global = this; 

    define(function(){ 
    global.x = ... 
    global.y = ... 
    }); 
})(); 

これではないので、我々はすぐに(そういない特定の特別なthis値で呼び出され呼び出し、および外側の無名関数strictモードで)、グローバルオブジェクトをthisとして受け取ります。 (strictモードでは、代わりにundefinedが返されます)。thisを匿名関数内の変数(global)に取り込み、defineに渡す関数からそれを使います。

+0

これは良いアイデアですが、即時呼び出し関数に自分のコードを埋め込む必要のない 'define()'関数の中にメカニズムがあるのか​​どうか疑問です。 – AlexStack

13

windowオブジェクトを返すモジュールを作成することをお勧めします。これは単体テストの目的(モック依存関係)に特に便利です。

window.js

define(function(){ 
    return window; 
}); 

app.js

define(['window'], function(win) { 
    // Manipulate window properties 
    win.foo = 1; 
    console.log(win.foo);  
}); 
+0

だから、モジュールが他のコンテキストを動かすように、グローバルオブジェクトを実際にしたいのですが? – gman

+0

私はあなたが正しく@gmanを理解していれば...私たちのコードはiframe内にあると言っていますが、一番上のグローバルオブジェクトが必要です。私たちは、これを行うことができます: '//コードはiframe 内の定義([ '窓']、機能(勝利){ VAR topWin = win.top; //は、IFRAMEのウィンドウのプロパティを操作する win.foo = 1; にconsole.log(win.foo); //トップ画面のプロパティ topWin.foo = 2操作し; にconsole.log(topWin.foo); を}); ' –

+0

申し訳ありませんが、私は私が実行していない意味しましたブラウザではグローバルオブジェクトは 'window'ではありません。 – gman

5

もstrictモードで動作する@ TJCrowderの答え、上のバリエーション:

(function(global) { 
    define(function() { 

     global.a="this"; 
     global.b="that"; 

    }); 
})(this); 

ことですぐに呼び出された関数を呼び出す引数 'this'(関数の外側がグローバルスコープである)を使用すると、グローバルスコープが何であれ、引数として 'グローバル'に渡されます。

これにより、 'window'オブジェクトへのハードコーディングも回避されます。これは、ブラウザ以外の環境では適用されないためです。

+0

ファイルにそのコードを入れてNodeに渡すと、strictモードであるかどうかに関わらず 'this'は '{}'です。 – Louis

関連する問題