在javascript中按字符串名称设置变量?

时间:2011-10-25 12:55:48

标签: javascript

//window["Fluent"]["Include"]

function setGlobalVariableByName(name,value)
{
    var indexes = name.split(".");
    var variable = null;
    $.each(indexes, function()
    {
        if (variable == null){
            variable = window[this];
        }else{
            variable = variable[this];
        }
    });

    variable = value;
}

setGlobalVariableByName("Fluent.Include.JqueryPulse",true);
console.log(Fluent.Include.JqueryPulse) // prints false
显然,这不起作用。如果我只是想得到变量的值,它会起作用,但不能用于设置它。

window["Fluent"]["Include"]["JqueryPulse"] = true;
console.log(Fluent.Include.JqueryPulse) // prints true

如何在不使用eval的情况下实现这样的目标? 我需要一些方法以编程方式为此添加数组索引,我猜是


以下作品,您是否可以建议一种更好的方法来对其进行编码以使其更干?

function setGlobalVariableByName(name,value)
{
    var indices = name.split(".");
    var parent;
    $.each(indices, function(i)
    {
        if(i==indices.length-1){
            if (!parent){
                window[this] = value;
            }else{
                parent[this] = value;
            }
        }else if (!parent){
            parent = window[this];
        }else{
            parent = variable[this];
        }
    });
}

setGlobalVariableByName : function(name, value)
{
    var indices = name.split(".");
    var last = indices.pop();
    var parent;
    $.each(indices, function(i)
    {
        if (!parent){
            parent = window[this];
        }else{
            parent = variable[this];
        }
    }); 
    if (!parent){
        window[last] = value;
    }else{
        parent[last] = value;
    }
}

2 个答案:

答案 0 :(得分:5)

您需要致电

variable[this] = value 

不知。因此,您需要在重新使用姓氏之前打破已拆分字符串的循环,然后分配值。

你需要致电:

variable = window['Fluent']['Include']; // build this in a loop
variable['JqueryPulse'] = someValue; // then call this

答案 1 :(得分:0)

最终,您只需构建一个对象链并将链中的最终项目设置为值。另外,我会添加一个检查,以确保不会覆盖已经是对象的项目,以便它们的现有属性不会丢失:

//bootstrap the object for demonstration purposes--not necessary to make code work
window.Fluent = {
  Include: {
    foo: 'bar', //don't want to lose this'
    JqueryPulse: false //want to set this to true
  }
};

//define function
function setGlobalItemByName( name, value )
{
  var names,
      finalName,
      //no need to figure out if this should be assigned in the loop--assign it now
      currentOp = window;

  if( typeof name === 'string' && name !== '' )
  {
    names = name.split( '.' );
    //no need to track where we are in the looping--just pull the last off and use it after
    finalName = names.pop();

    $.each( names, function()
    {
      //If the current item is not an object, make it so. If it is, just leave it alone and use it
      if( typeof currentOp[this] !== 'object' || currentOp[this] === null )
      {
        currentOp[this] = {};
      }

      //move the reference for the next iteration
      currentOp = currentOp[this];
    } );

    //object chain build complete, assign final value
    currentOp[finalName] = value;
  }
}

//use function
setGlobalItemByName( 'Fluent.Include.JqueryPulse', true );


//Check that Fluent.Include.foo did not get lost
console.log( Fluent.Include.foo );
//Check that Fluent.Include.JqueryPulse got set
console.log( Fluent.Include.JqueryPulse );

但是,即使你在页面上有jQuery,我也可以不使用jQuery。不需要为每个index执行函数的开销。

//bootstrap the object for demonstration purposes--not necessary to make code work
window.Fluent = {
  Include: {
    foo: 'bar', //don't want to lose this'
    JqueryPulse: false //want to set this to true
  }
};

//define function
function setGlobalItemByName( name, value )
{
  var names,
      finalName,
      indexCount,
      currentIndex,
      currentName,
      //no need to figure out if this should be assigned in the loop--assign it now
      currentOp = window;

  if( typeof name === 'string' && name !== '' )
  {
    names = name.split( '.' );
    //no need to track where we are in the looping--just pull the last off and use it after
    finalName = names.pop();

    indexCount = names.length;
    for( currentIndex = 0; currentIndex < indexCount; currentIndex += 1 )
    {
      currentName = names[currentIndex];

      //If the current item is not an object, make it so. If it is, just leave it alone and use it
      if( typeof currentOp[currentName] !== 'object' || currentOp[currentName] === null )
      {
        currentOp[currentName] = {};
      }

      //move the reference for the next iteration
      currentOp = currentOp[currentName];
    }

    //object chain build complete, assign final value
    currentOp[finalName] = value;
  }
}

//use function
setGlobalItemByName( 'Fluent.Include.JqueryPulse', true );


//Check that Fluent.Include.foo did not get lost
console.log( Fluent.Include.foo );
//Check that Fluent.Include.JqueryPulse got set
console.log( Fluent.Include.JqueryPulse );