2011-10-25 88 views
3
//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 

这显然不起作用。如果我只是想获得变量的值,但不能设置它,它会起作用。在JavaScript中通过字符串名称设置变量?

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; 
    } 
} 
+0

他们确实存在,我只是这样解释它的问题。变量'Fluent.Include.JqueryPulse'已经存在,其值为假,我想将其设置为true。但我不需要初始化任何东西 – bevacqua

+0

以下是不同的版本:http://jsfiddle.net/3WtJM/2/ –

+0

@Nico - 你说过,“变量Fluent.Include.JqueryPulse已经存在了...”小心你不要跺脚那些已经存在的物品,因为你会失去它们的属性。查看我的回答和代码注释以避免此问题。 – JAAulde

回答

5

你需要调用

variable[this] = value 

莫名其妙。因此,您需要在修改姓氏之前中断拆分字符串的循环,然后分配值。

Ultimatively你需要调用:

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

不错,我不会想到这个,谢谢! – bevacqua

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); 
+1

'.pop()'的建议很好,我会用它。 – bevacqua

+0

@Nico酷,很高兴你找到了一些有用的东西。 – JAAulde

相关问题