如何在Javascript中声明动态局部变量

Pau*_*bin 13 javascript

我想动态创建一个局部变量.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>
Run Code Online (Sandbox Code Playgroud)

我尝试了以下代码.

    <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>
Run Code Online (Sandbox Code Playgroud)

但是生成的变量在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>
Run Code Online (Sandbox Code Playgroud)

这有效.但我正在寻找替代/更好的解决方案.没有评估可以做到吗?

编辑: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>
Run Code Online (Sandbox Code Playgroud)

一切正常.但它实际上是创建全局变量而不是在函数中创建变量.

传递给createVariables()函数的"self"是窗口.我不确定为什么会这样.我正在为自己分配功能范围.我不确定这里发生了什么.无论如何,在这种情况下创建全局变量.

如果我的问题不明确,

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

1)我在一个函数里面.
2)我调用另一个函数,它返回一个map [此映射包含变量的名称和值].
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>
Run Code Online (Sandbox Code Playgroud)

Chr*_*ker 8

根据您希望变量的范围,可以通过几种不同的方式实现.

全球范围

要将变量放在全局范围中,您可以使用window[varName]:

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

createVariables({
    'foo':'bar'
});
console.log(foo); // output: bar
Run Code Online (Sandbox Code Playgroud)

试试吧: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
Run Code Online (Sandbox Code Playgroud)

试试吧: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);
Run Code Online (Sandbox Code Playgroud)

试试吧: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
Run Code Online (Sandbox Code Playgroud)

试试吧:http://jsfiddle.net/X3p6k/3/

文档


Jon*_*uin -1

你需要这样的东西吗?

function createVariables(properties, context){
 for( var variable in properties){
    context[variable] = properties[variable ];
 }
}
Run Code Online (Sandbox Code Playgroud)

因此,调用 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>
Run Code Online (Sandbox Code Playgroud)

  • 这与创建局部变量相反。它之所以有效,是因为在非严格模式下,上下文中的“this”被传递**IS**全局对象,并且您因此向全局对象添加属性。请注意,运行此函数后,“var1”和“var2”在任何地方都可用,而不仅仅是在该函数中。这个jsfiddle显示:http://jsfiddle.net/goasfgp8/ (2认同)