13

ローカル変数を動的に作成したい。JavaScript: ループの変数を動的に作成することは、まさに私が探しているものではありません。配列は必要ありません。ローカル変数のようにアクセスしたい。

何かのようなもの:

    <script type="text/javascript">
        var properties = new Object();
        properties["var1"] = "value1";
        properties["var2"] = "value2";

        createVariables(properties);

        function createVariables(properties)
        {
            // This function should somehow create variables in the calling function. Is there a way to do that?
        }
        document.write("Outside the function : " + var1 + "<br>");
        document.write("Outside the function : " + var2 + "<br>");
    </script>

次のコードを試しました。

    <script type="text/javascript">
        var properties = new Object();
        properties["var1"] = "value1";
        properties["var2"] = "value2";

        createVariables(properties);

        function createVariables(properties)
        {
            for( var variable in properties)
            {
                try
                {
                    eval(variable);
                    eval(variable + " = " + properties[variable] + ";");
                }
                catch(e)
                {
                    eval("var " + variable + " = '" + properties[variable] + "';");
                }
            }
            document.write("Inside the function : " + var1 + "<br>");
            document.write("Inside the function : " + var2 + "<br>");
        }
        document.write("Outside the function : " + var1 + "<br>");
        document.write("Outside the function : " + var2 + "<br>");
    </script>

ただし、生成された変数は createVariables() の外ではアクセスできません。

今、私はこの解決策を持っています。

    <script type="text/javascript">
        var properties = new Object();
        properties["var1"] = "value1";
        properties["var2"] = "value2";

        function createVariables(properties)
        {
            var str = "";
            for( var variable in properties)
            {
                str += "try{";
                str += "eval('" + variable + "');";
                str += "eval(\"" + variable + " = properties['" + variable + "'];\");";
                str += "}";
                str += "catch(e){";
                str += "eval(\"var " + variable + " = properties['" + variable + "'];\");";
                str += "}";
            }
            return str;
        }

        eval(createVariables(properties));
        document.write("Outside the function : " + var1 + "<br>");
        document.write("Outside the function : " + var2 + "<br>");
    </script>

これは機能します。しかし、代替/より良い解決策を探しています。evalなしでそれを行うことは可能ですか?

編集: 04-7 月

やあ、

@Jonathanが提案したものと同様の解決策を試しました。

    <script type="text/javascript">

    var startFunc = function(){
        var self = this;

        self.innerFunc = function innerFunc(){
            var properties = new Object();
            properties["var1"] = "value1";
            properties["var2"] = "value2";
            properties["var3"] = "value3";

            function createVariables(caller, props) {
                 for(i in props) { 
                     caller[i] = props[i];
                 }  
                 caller.func1();
            }
            createVariables(self, properties);
            console.log( var1 );
        }

        self.func1 = function func1(){
            console.log( "In func 1" );
            console.log( var2 );
        }

        innerFunc();
        console.log( var3 );
    }

    startFunc();


    </script>

これはすべてうまくいきます。しかし、実際には、関数内で変数を作成するのではなく、グローバル変数を作成しています。

createVariables() 関数に渡される「self」はウィンドウです。なぜそれが起こっているのかわかりません。関数スコープを自己に割り当てています。ここで何が起こっているのかわかりません。この場合、とにかくグローバル変数を作成しています。

私の質問が明確でない場合は、

私が求めているのは、呼び出し元でローカル変数を作成することです。シナリオはこんな感じ

1) 私は関数の中にいます。
2) マップを返す別の関数を呼び出します [このマップには、変数の名前と値が含まれています]。
3) 変数がまだ定義されていない場合は、すべての変数を動的に作成したいと考えています。[グローバル/ローカル] で既に定義されている場合は、それらを更新したいと思います。
4) これらの変数が作成されたら、コンテキストなしでそれらにアクセスできるはずです。[変数名のみ]

    <script type="text/javascript">
        function mainFunc()
        {
            var varibalesToBeCreated = getVariables();
            createVariables(varibalesToBeCreated);

            alert(var1);
            alert(var2);
        }

        function createVariables(varibalesToBeCreated)
        {
            // How can I implement this function, 
            // such that the variables are created in the caller? 
            // I don't want these variables this function.
        }

        function getVariables()
        {
            var properties = new Object();
            properties["var1"] = "value1";
            properties["var2"] = "value2";  
        }


        mainFunc();
    </script>
4

7 に答える 7

9

変数に持たせたいスコープに応じて、これはいくつかの異なる方法で達成できます。

グローバル スコープ

変数をグローバルスコープに配置するには、次を使用できますwindow[varName]

function createVariables(variables) {
    for (var varName in variables) {
        window[varName ] = variables[varName ];
    }
}

createVariables({
    'foo':'bar'
});
console.log(foo); // output: bar

試してみてください: http://jsfiddle.net/nLt5r/

グローバル スコープは汚い公共の場所です。どのスクリプトでも、このスコープ内の変数の読み取り、書き込み、または削除を行うことができます。このため、同じ変数名を使用する別のスクリプトを壊したり、別のスクリプトがあなたのものを壊したりするリスクがあります。

関数スコープ ( を使用this)

関数のスコープ ( this.varName) で変数を作成するには、次を使用できますbind

var variables = {
    'foo':'bar'
};
var func = function () {
    console.log(this.foo);
};
var boundFunc = func.bind(variables);
boundFunc(); // output: bar

試してみてください: http://jsfiddle.net/L4LbK/

バインドされた関数参照の処理によっては、このメソッドは変数の外部変更に対してわずかに脆弱です。アクセスboundFuncできるものはすべて、を使用して値の値を変更または参照できboundFunc.varName = 'new value';ます。ユース ケースによっては、これが有利になる場合があります。

関数スコープ (引数を使用)

apply値の配列を引数として渡すために使用できます。

var variables = [
    'bar'
];
var func = function (foo) {
    console.log('foo=', foo);
};
func.apply(null, variables);

試してみてください: http://jsfiddle.net/LKNqd/

引数は本質的に一時的なものであるため、変数配列を変更して関数を再呼び出しする場合を除いて、「外部」が値に干渉したり値を参照したりすることはできません。

一時的なグローバル スコープ

そして、グローバル スコープを一時的に使用する小さなユーティリティ関数を次に示します。この関数は、グローバル スコープも使用するコードにとって危険です。これにより、他のスクリプトが作成した変数が爆発する可能性があります。自己責任で使用してください。

var withVariables = function(func, vars) {
   for (var v in vars){
       this[v] = vars[v];
   }
   func();
   for (var v in vars){
       delete this[v];
   }
};

// using an anonymous function
withVariables(
    function () {
        console.log('anonymous: ', foo);   
    },
    {
        'foo':'bar'   
    }
); // output: bar

// using a function reference
var myFunction =function () {
    console.log('myFunction: ', foo);   
};
withVariables(myFunction, {
    'foo':'bar'   
}); // output: bar

console.log(foo); // output: undefined

試してみてください: http://jsfiddle.net/X3p6k/3/

ドキュメンテーション

于 2013-06-26T14:19:55.507 に答える
2

ローカル変数とグローバル変数の両方を動的に作成する短いコード スニペットを作成しました。

function createVar(name,dft){
 this[name] = (typeof dft !== 'undefined')?dft:"";
}

createVar("name1","gaurav"); // it will create global variable
createVar("id");// it will create global variable

alert(name1);
alert(id);
function outer(){
 var self = this;
  alert(self.name1 + " inside");
}
createVar.call(outer,"name1","saurav"); // it will create local variable
outer.call(outer); // to point to local variable.
outer(); // to point to global variable
alert(name1);

これが役立つことを願っています よろしく Gaurav Khurana

于 2015-11-09T11:34:50.567 に答える
1

この回答は、上記のいくつかの回答とほぼ同じですが、ここでは、eval を使用する場合と使用しない場合の単純化されたサンプルを示します。最初に eval を使用します (非推奨):

var varname = 'foo';  // pretend a user input that
var value = 42;
eval('var ' + varname + '=' + value);

または、eval を使用しない場合:

var varname = prompt('Variable name:');
var value = 42;
this[varname] = value;

これが役立つことを願っています。

ソース: https://www.rosettacode.org/wiki/Dynamic_variable_names#JavaScript

于 2016-04-03T11:27:02.923 に答える
0

このようなものが必要ですか?

function createVariables(properties, context){
 for( var variable in properties){
    context[variable] = properties[variable ];
 }
}

したがって、 ascreateVariables(properties, this)を呼び出すと、現在のスコープが からの値で埋められますproperties


<script type="text/javascript">
        var properties = new Object();
        properties["var1"] = "value1";
        properties["var2"] = "value2";

        createVariables(properties, this);

        document.write("Outside the function : " + var1 + "<br>");
        document.write("Outside the function : " + var2 + "<br>");
    </script>
于 2013-06-26T14:16:17.430 に答える
0

関数が呼び出されている場所のスコープが必要なthisため、関数に渡します

var properties = new Object();
properties["var1"] = "value1";
properties["var2"] = "value2";
function createVariables(context) {
     for(i in properties) { 
         context[i] = properties[i];
     }   
}
createVariables(this);
console.log( var1 );
于 2013-06-26T14:18:24.863 に答える