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>

这行得通。但我正在寻找替代/更好的解决方案。是否可以在没有评估的情况下做到这一点?

编辑:7 月 4 日

你好,

我尝试了类似于@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”是 window. 我不确定为什么会这样。我将功能范围分配给自我。我不确定这里发生了什么。在这种情况下,无论如何都要创建全局变量。

如果我的问题不清楚,

我所追求的是在调用者中创建局部变量。场景就像

1)我在一个函数里面。
2)我调用另一个函数,它返回给我一个地图[这个地图包含一个变量的名称和值]。
3)我想动态创建所有变量,如果它们尚未定义。如果它们已经定义 [global/local],我想更新它们。
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

这是基于 Chris Baker 回答的工作示例:函数范围(使用参数)

    function myFn() {
      function keyList(params) {
        var str = '';
        for (var key in params) {
          if (params.hasOwnProperty(key)) {
            str += ',' + key;
          }
        }
        return str.length ? str.substring(1) : str;
      }

      function valueList(params) {
        var list = [];
        for (var key in params) {
          if (params.hasOwnProperty(key)) {
            list.push(params[key]);
          }
        }
        return list;
      }
      var params = {
        'var1': 'value1',
        'var2': 'value2'
      };
      var expr = 'document.write("Inside the function : " + var1 + "<br>")'
      var fn;
      eval('var fn = function(' + keyList(params) + '){' + expr + '};');
      fn(valueList(params));
    }

    myFn();

于 2015-03-17T05:51:56.153 回答
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

下面的示例演示了with如何从对象中获取值。

var obj = { a : "Hello" }
with(obj) {
  alert(a) // Hello
}

但我想注意:with 已弃用!

于 2016-02-16T15:53:37.303 回答
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 回答