2011-10-25 89 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

相關問題