4

オブジェクトと自己実行匿名関数を使用して名前空間を作成することを検討しています。どちらがより良い選択肢と考えられていますか?

オブジェクトを使用して、競合を防ぐのに十分な一意の名前「myAppName」を付けていますか?

var myAppName = { 
    val1: "abc", 
    val2: "xyz",
    myFunc1: function() {
      return this.val2;  
    }
}

console.log(myAppName.val1);  // abc
console.log(myAppName.myFunc1());  // xyz

自己実行匿名関数の使用:

(function () {
val1 = "abc";
    var val2 = "xyz";

    myFunc1 = function() {
        return val1;   
    }

    var myFunc2 = function() {
        return val2;
    }
})();

console.log(val1);  // abc
console.log(myFunc1());  // abc
console.log(myFunc2());  // xyz

上記の自己実行関数のコードでは、それらはすべて実行されているようです。変数名や関数名の前に var を付けたり付けなかったりすることに意味はありますか? よくわかりません。変数と関数をプライベートおよびパブリックにする方法はありますか? それとも、自己実行関数内のすべてがプライベートですか?

以下のように自己実行関数の前に「var」を使用するとどうなりますか?

var myAppName = (function () {
val1 = "abc";
    var val2 = "xyz";

    myFunc1 = function() {
        return val1;   
    }

    var myFunc2 = function() {
        return val2;
    }
})();
4

2 に答える 2

4

すべてのコードを 1 つの名前空間に配置すると、名前の衝突を避けることができます。衝突が発生した場合は、コードを変更して対処する方がはるかに簡単です。

すべてを公開する必要がある場合は、最初のコード例で問題ありません。いくつかのものを非公開にしたい場合は、次のように匿名ですぐに実行される関数を使用します。

var myApp = (function() {
    var privateValue = 'abc'; // Don't forget "var" here.

    function privateFunction() {
        return privateValue;
    }

    return {
        publicValue: 'xyz',

        publicFunction: function() {
            return privateFunction();
        }
    }
})();

無名関数がパブリック変数と関数を含むオブジェクトを返す方法に注目してください。「privateValue」の前に「var」を置かない場合、ローカル変数を定義していません。代わりに、グローバル変数を参照しています (これは実際には「ウィンドウ」オブジェクトのプロパティです)。

jQuery を使用している場合は、次のことをお勧めします。

(function(window, $, undefined) {

    var myApp = (function() {
        var privateValue = 'abc'; // Don't forget "var" here.

        function privateFunction() {
            return privateValue;
        }

        return {
            publicValue: 'xyz',

            publicFunction: function() {
                return privateFunction();
            }
        }
    })();

    // Put myApp in the global scope.
    window.myApp = myApp; 

})(window, jQuery);

このようにして、$()の代わりに安全に使用できますjQuery()undefined定数として扱っても安全です。また、誰かがウィンドウ オブジェクトをオーバーライドした場合にも、より簡単に対処できます。

于 2013-03-22T15:36:06.573 に答える
4

私の最初の回答は、元の質問に対処し、名前空間を設定する方法を示しようとしました。その回答に追加する代わりに、コメントの質問に対処するために2番目の回答を最初の回答に追加することにしました。

グローバル変数は、実際にはwindowオブジェクトのプロパティです。関数の外で使用する場合varは、グローバル変数を定義しています。var関数内で使用する場合は、ローカル変数を定義しています。someValueで宣言せずに変数を参照するとvar、 を参照したことになりますwindow.someValue

次のコードは、グローバル変数を設定するさまざまな方法と、ローカル変数を定義する 1 つの方法を示しています。

window.global1 = 'abc';
global2 = 'def';
var global3 = "ghi";

(function() {
    window.global4 = 'jkl';
    global5 = 'mno';
    var local1 = 'xyz';
})();

console.log(global1); // 'abc'
console.log(global2); // 'def'
console.log(global3); // 'ghi'
console.log(global4); // 'jkl'
console.log(global5); // 'mno'
console.log(local1);  // ReferenceError: local1 is not defined

一般に、グローバル変数の設定を制限する必要があります (少なくとも JavaScript ライブラリを作成する場合)。名前空間は基本的に単なるグローバル変数です。他のすべてをその名前空間に配置すると、単一のグローバル変数のみが追加されます。

global2以上のようなグローバル変数の設定を避けることもベストプラクティスだと思いますglobal5。代わりにvar、関数の一部 ( など) を使用するか、オブジェクトglobal3にプロパティを設定する(やなど) 必要があります。windowglobal1global4

私の他の回答からコード例を借りると、次のような名前空間を作成できます。

var myApp = (function() {
    var privateValue = 'abc'; // Don't forget "var" here.

    function privateFunction() {
        return privateValue;
    }

    return {
        publicValue: 'xyz',

        publicFunction: function() {
            return privateFunction();
        }
    }
})();

次のようにして同じことを達成することもできましたが、これは悪いスタイルだと思います。

(function() {
    var privateValue = 'abc'; // Don't forget "var" here.

    function privateFunction() {
        return privateValue;
    }

    myApp = {
        publicValue: 'xyz',

        publicFunction: function() {
            return privateFunction();
        }
    }
})();

どちらもグローバル変数を設定していmyAppますが、後者よりも前者の方がわかりやすいと思います。

明確にするために、どちらの場合も、パブリック変数を as としてアドレス指定し、myApp.publicValueを使用してパブリック関数を呼び出します。無名関数の外では、 ormyApp.publicFunction()を参照することはできません。privateValueprivateFunction

于 2013-03-23T04:01:58.320 に答える