2012-11-21 24 views
7

無論如何,無論是本地還是通過庫,都可以在Javascript對象上使用自動版本?有Javascript支持Javascript對象的自動化嗎?

IE,假設foo是沒有屬性的對象,只能做foo.bar.baz = 5而不需要foo.bar = {}; foo.bar.baz = 5

+4

純粹原生,我不這麼認爲。 'undefined'不可擴展或不可改變,這是我能想到的,而不用通過函數傳遞的唯一方法。 – Snuffleupagus

+2

否參見http://stackoverflow.com/questions/7691395/autovivification-and-javascript – lbstr

+0

@Ibstr,這個問題在引用自動版化和JavaScript的同時,並不是問我同樣的問題。 –

回答

5

你不能完全用你想要的語法來完成它。但是,像往常一樣,在JS你可以編寫自己的功能:

function set (obj,keys,val) { 
    for (var i=0;i<keys.length;i++) { 
     var k = keys[i]; 
     if (typeof obj[k] == 'undefined') { 
      obj[k] = {}; 
     } 
     obj = obj[k]; 
    } 
    obj = val; 
} 

所以現在你可以這樣做:

// as per you example: 
set(foo,['bar','baz'],5); 

沒有如果barbaz定義令人擔憂。如果你不喜歡函數調用中的[..],你總是可以迭代arguments對象。

+0

我正在設置字典值,如set('dict_obj',[0,'User'],5)。但是我無法使用像Console.log('dict_obj [0] ['User'])這樣的調用來返回我設置的值。我無法返回值5.您是否看到我如何使用它的任何錯誤? – ouonomos

+0

@ouonomos:你做錯了,你在字符串「dict_obj''上設置值而不是對象'dict_obj'。 – slebetman

+0

我很抱歉,我打錯了。我實際做的是:\t \t \t \t lastposxns = {}; \t \t \t \t grpname = 0; \t \t \t \t tempname ='abc'; \t \t \t \t ypos = 5; \t \t \t dict_set(lastposxns [grp,tempname],ypos);其中dict_set是autoviv函數。但console.log(lastposxns [0] ['abc'])不返回值5. – ouonomos

2

純粹原生地,我不這麼認爲。 undefined不可擴展或不可更改,這是我可以想象的做法,而不必通過函數傳遞。

0

或者您可以使用基於eval的解決方案。這是醜陋的,不推薦。

function av(xpr) { 

    var res = ""; 
    var pos = 0; 
    while (true) { 

     var pos = xpr.indexOf("[",pos); 
     if (pos == -1) break; 
     var frag = xpr.substr(0,pos); 
     pos++; 

     res += "if (typeof(" + frag + ") != 'object') " + frag + " = {};\n"; 
    } // while 

    return res + xpr; 
} // av() 


function main() { 

    var a = {}; 
    a["keep"] = "yep"; 
    eval(av('a[1][1]["xx"] = "a11xx"; ')); 
    eval(av('a[1][2]["xx"] = "a12xx"; ')); 

    console.log(a); 
} // main() 
2

我有一個願望,所以我寫了a package to handle it

% npm install autovivify 
% node 
> Av = require('autovivify') 
> foo = new Av() 
{} 
> foo.bar.baz = 5 
5 
> foo 
{ bar: { baz: 5 } } 
> 

它甚至會做陣列,數字標:

> foo = new Av() 
> foo.bar.baz[0] = 'hum' 
> foo 
{ bar: { baz: [ 'hum' ] } } 
0

@ slebetman的代碼似乎沒有工作。最後一個鍵不應該被分配一個空對象,而是val。此代碼工作:

function autoviv(obj,keys,val) { 
    for (var i=0; i < keys.length; i++) { 
    var k = keys[i]; 
    if (typeof obj[k] === 'undefined') { 
     if(i === keys.length-1) { 
     obj[k] = val; 
     return; 
     } 
     obj[k] = {}; 
    } 
    obj = obj[k]; 
    } 
} 

foo = {} 
autoviv(foo,['bar','baz'],5); 
console.log(foo.bar.baz); 
5 
+0

嗨馬克,我懷疑,有沒有什麼好的方法來捕獲使用角度js的屏幕截圖,如果是的話,你可以請檢查這個https://stackoverflow.com/questions/44602309/making-a-屏幕正確,圖像捕獲的 - - 使用 - jQuery的 –