2013-03-17 45 views
4

我正在做一個需要通過JSON將Perl對象傳遞給javascript的項目。我在「中間」對象定義方面面臨一個問題。有沒有辦法只通過分配屬性來自動創建一個JavaScript對象?

在Perl中,對象由散列表示,程序員不必定義任何「在中間」。一旦創建了一個屬性,所有的中間對象都會自動創建爲散列引用。例如

$graph{chart}{yAxis}{title} = "Temperature Tracking"; 

然而,一旦這個對象傳遞給JavaScript中,如果我想在「中間」對象添加任何新特性,如:

graph.chart.xAxis.title = "Time Sequence"; 

我將有一個「不確定的圖表。 chart.xAxis「錯誤。與Perl不同的是,如果我們只是爲它指定一個屬性,Javascript不會自動創建對象。

目前,我必須使用以下解決方案:

if (!graph.chart.xAxis) { 
    graph.chart.xAxis = {}; 
    graph.chart.xAxis.title = "Time Sequence"; 
} 

不幸的是,在我們的項目從Perl中傳遞的對象是非常動態的,有很多是JavaScript可能不知道其他對象。上面的方法使得JS代碼非常冗長和「看起來很醜陋」。有沒有更好的解決方案,使Javascript的行爲像Perl,這意味着我不必手動創建中間對象?

+0

好了,你可以簡單地編寫創建所有缺少的對象的一個​​小功能。 – Niko 2013-03-17 09:36:13

+0

@Niko我不確定,但JavaScript沒有autovivification,對不對?你怎麼看這個函數檢查丟失的對象? – gaussblurinc 2013-03-17 09:39:30

+0

@Ioldop請參閱下面的答案。你必須使用字符串來做到這一點。 – Niko 2013-03-17 09:52:10

回答

3

我不知道這是否符合您的要求,但一個簡單的函數來創建缺少的對象可能是這樣的:

function insertNode(obj, node, value) { 
    var segments = node.split('.'); 
    var key = segments.pop(); 
    var ref = obj; 

    while (segments.length > 0) { 
     var segment = segments.shift(); 
     if (typeof ref[segment] != 'object') { 
      ref[segment] = {}; 
     } 
     ref = ref[segment]; 
    } 

    ref[key] = value; 
}; 

var x = {}; 
insertNode(x, 'foo.bar.baz', 'hello world'); 
alert(x.foo.bar.baz); // "hello world" 

演示:http://jsfiddle.net/sNywt/1/

+0

非常感謝!尼科。我做了一些測試,你的解決方案很好。現在我明白在JavaScript中似乎沒有內置功能來處理這個問題。 – BebbaPig 2013-03-17 11:00:40

2

你可能有興趣在一個名爲庫steeltoe

steelToe(graph).set('chart.xAxis.title', 'Time Sequence'); 
+0

太棒了!這似乎是最直接的解決方案。 – BebbaPig 2013-03-17 10:44:23

2

不知道,如果它適合你的情況,但你可以檢查是否存在財產和創建如果不存在,如:

function use_or_create(obj, prop) { 
    return (obj.hasOwnProperty(prop)) ? true : (obj[prop] = {}); 
} 
var graph.chart = {}; //your object 
//function call to check if property exist before trying to use it 
use_or_create(graph.chart, 'xAxis'); //check if xAxis exists and creates one if doesnot 
graph.char.xAxis.title = "tested"; 
+0

非常感謝,Sudhir。這個解決方案比我的原始解決方案好得多,但我仍然需要測試中間每個嵌套對象的存在。 – BebbaPig 2013-03-17 10:40:54

2

也許這Object擴展會做什麼:

Object.prototype.val = function(prop,val){ 
    prop = /\./i.test(prop) ? prop.split('.') : prop; 
    if (prop.constructor === Array){ 
     var objnow = this, pr; 
     while (pr = prop.shift()){ 
     if (!objnow[pr]){ 
      objnow[pr] = {}; 
     } 
     if (!prop.length) { 
      objnow[pr] = val; 
     } 
     objnow = objnow[pr]; 
     } 
     for (var l in objnow){ 
      this[l] = objnow[l]; 
     } 
    } else { 
     this[prop] = val; 
    } 
} 
// usage 
var myO = {}; 
myO.val('a.b.c',3);  //=> myO.a.b.c = 3 
myO.val('someprop',3);  //=> myO.someprop = 3 
myO.val('a.b.someprop',5); //=> myO.a.b.someprop = 3 
+0

是的,它是,糾正它。謝謝 ;) – KooiInc 2013-03-17 11:13:29

相關問題