4

別の関数で使用される2つのパラメーターを初期化する.jsファイルがあります。

var submyvar1;
var submyvar2;

function init(myvar1 , myvar2){
    submyvar1= myvar1;
    submyvar2= myvar2;
}

function (){
    //subvar1 & subvar 2 used here
}

このようなグローバル変数を宣言するのは悪い習慣ですか?

もしそうなら、代替手段は何ですか、オブジェクトで.jsファイル全体をラップしますか?

4

4 に答える 4

4

少なくともそれは良い習慣ではありません、あなたは即時に呼び出された関数式を使うことができます:

(function() {
    var x;
    var y;

    window.init = function(xValue, yValue) {
        x = xValue;
        y = yValue;
    }

    window.doWhateverYouWant = function() {
        console.log(x + y);
    }
}());

この.jsファイルの外部でグローバル変数にアクセスする必要がない限り、このパターンを使用できます。.jsファイルまたは要素間のクロスアクセス<script>が必要な場合、グローバル変数は単純なソリューションです(ただし、代わりにAMDまたはsth elseを使用できます)。

于 2013-01-29T09:21:18.423 に答える
2

「RevealingModulePattern」を使用した実装の可能性に関するここの素晴らしい記事: http://enterprisejquery.com/2010/10/how-good-c-habits-can-encourageで説明されているように、明らかにするモジュールパターンを使用することにしました。 -bad-javascript-habits-part-1 /

受け入れられた答えと非常によく似ています。

上記のenterprisejqueryから貼り付けたパターンの説明は次のとおりです。

We looked at the Self-Executing Anonymous Function earlier as a pattern you could use to keep all your code private. As it turns out, you can actually modify the pattern somewhat so that you can achieve the same benefits of the Revealing Module Pattern. Not only can we achieve public and private properties and methods, but we can also provide an easy way to extend the namespace while keeping the content protected from the global namespace. In addition, the following pattern can protect the $ from conflicting with other JavaScript libraries and also protect undefined from being redefined.

Take a look at the following example, and we will walk through the code explaining the key changes to the pattern.


//Self-Executing Anonymous Func: Part 2 (Public & Private)
(function( skillet, $, undefined ) {
    //Private Property
    var isHot = true;

    //Public Property
    skillet.ingredient = "Bacon Strips";

    //Public Method
    skillet.fry = function() {
        var oliveOil;

        addItem( "\t\n Butter \n\t" );
        addItem( oliveOil );
        console.log( "Frying " + skillet.ingredient );
    };

    //Private Method
    function addItem( item ) {
        if ( item !== undefined ) {
            console.log( "Adding " + $.trim(item) );
        }
    }    
}( window.skillet = window.skillet || {}, jQuery ));

//Public Properties
console.log( skillet.ingredient ); //Bacon Strips

//Public Methods
skillet.fry(); //Adding Butter & Fraying Bacon Strips

//Adding a Public Property
skillet.quantity = "12";
console.log( skillet.quantity ); //12

//Adding New Functionality to the Skillet
(function( skillet, $, undefined ) {
    //Private Property
    var amountOfGrease = "1 Cup";

    //Public Method
    skillet.toString = function() {
        console.log( skillet.quantity + " " + 
                     skillet.ingredient + " & " + 
                     amountOfGrease + " of Grease" );
        console.log( isHot ? "Hot" : "Cold" );
    };    
}( window.skillet = window.skillet || {}, jQuery ));

try {
    //12 Bacon Strips & 1 Cup of Grease
    skillet.toString(); //Throws Exception
} catch( e ) {
    console.log( e.message ); //isHot is not defined
}
You can execute and modify the above code from jsFiddle.

First, since we have a Self-Executing Anonymous Function, we can actually provide some parameters to pass to it when it executes. In this case we are passing 2 arguments to the anonymous function.

The first argument looks quite strange. What is window.skillet = window.skillet || {} doing? The code checks to see if skillet exists in the global namespace (window). If it does not exist, then window.skillet is assigned an empty object literal. Using this approach we can build a library across JavaScript files. If another script uses the same technique, then it will pass in the existing instance and append logic to it. Inside the Anonymous Function, if we want something to be public, then we append it to the skillet object. Any other properties or methods will be considered private.

The second argument passed in jQuery. The benefit of this is that the named parameter is referenced as $, which allows us to refer to jQuery as $ within the Anonymous Function without having to worry that it will conflict with the $ declared in other JavaScript libraries. This is a common practice that you will most likely run across when looking at well written jQuery code.

You might notice a 3rd parameter to the Anonymous Function called undefined. Why did we add that parameter and why didn’t we pass an argument to it? In JavaScript, you can unfortunately redefine what undefined means. Imagine that some code somewhere deep in one of your 3rd party libraries redefines undefined to something strange like true. If anywhere in your code you test against undefined, then you code will most likely not behave like you intended. In JavaScript, if you have a parameter that doesn’t have a matching argument, then it’s value is set as undefined. By using this trick, it can save us from the bad code someone wrote to redefine undefined.

Pros

Gives you the ability to have public and private properties and methods
The code inside doesn’t use the Object Literal notation
Keeps undefined’s value as undefined in case someone overrode the value
Allows you to use $ inside your code without worrying about clashing with other libraries
Allows your library to grow across files using the “window.namespace = window.namespace || {}” technique
A common pattern that you will see in many libraries, widgets, and plugins
Cons

Slightly more complicated pattern, but not overly difficult to understand
If you are interested in digging deeper into some of the patterns I mentioned above then I encourage you to check out Klaus Komenda’s post entitled JavaScript Programming Patterns. The article provides an insightful view of how JavaScript patterns have changed over the years. 
于 2013-01-29T12:25:48.197 に答える
1

JavaScript:The Good Parts (ここにも要約されています)では、次のことが提案されています:

グローバル変数はプログラムの回復力を弱めるため、避ける必要があります。グローバル変数の使用を最小限に抑える1つの方法は、アプリケーション用に単一のグローバル変数を作成することです。

var MYAPP = {};

その変数は、アプリケーションのコンテナになります。

MYAPP.stooge = {
    "first-name": "Joe",
    "last-name": "Howard" };

グローバルフットプリントを単一の名前に減らすことで、他のアプリケーション、ウィジェット、またはライブラリとの不適切な相互作用の可能性を大幅に減らすことができます。MYAPP.stoogeが最上位構造を参照していることは明らかであるため、プログラムも読みやすくなります。

于 2013-01-29T09:43:41.483 に答える
1

グローバル名前空間が乱雑にならないように、可能な限り回避する必要があります。ただし、公開したいコードが少しある可能性があるため、その場合は問題ありません。たとえば、jQueryは明らかに変数jQuery$変数をグローバルにする必要があります(これは、変数をのプロパティにすることで実現しますwindow

これを回避するには、コードの後に​​角かっこを付けて関数にコードを含めることができます。

var mySingleGlobalVar = (function () {
    var submyvar1;
    var submyvar2;

    function init(myvar1 , myvar2){
        submyvar1= myvar1;
        submyvar2= myvar2;
    }

    function (){
        //subvar1 & subvar 2 used here
    }

    return init;
}());

すぐに実行される機能です。この例では、戻り値(init関数)をグローバル変数に割り当てました。これは、スクリプトが作成する唯一のグローバル変数です(すべてをで適切に宣言している限りvar)。

于 2013-01-29T09:25:04.780 に答える