2012-11-21 6 views
7

Czy mimo to, natywnie lub przez bibliotekę, można użyć autoworyzacji obiektów JavaScript?Czy istnieje biblioteka obsługująca autowykrywanie obiektów JavaScript?

IE, zakładając, że foo jest obiektem bez właściwości, może po prostu zrobić foo.bar.baz = 5 zamiast wymagać foo.bar = {}; foo.bar.baz = 5.

+4

Czysto natywnie, nie sądzę. 'undefined' nie jest rozszerzalne ani zmienne i jest to jedyny sposób, w jaki mógłbym to zrobić bez przekazywania go przez funkcję. – Snuffleupagus

+2

Nie. Zobacz http://stackoverflow.com/questions/7691395/autovivification-and-javascript – lbstr

+0

@Ibstr, to pytanie, odnosząc się do autoworyzacji i JavaScript, nie pyta o to samo, co ja. –

Odpowiedz

5

Nie można tego zrobić dokładnie zgodnie z żądaną składnią. Ale, jak zwykle, w JS można napisać własną funkcję:

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

więc teraz można to zrobić:

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

bez obawy jeśli bar lub baz są zdefiniowane. Jeśli nie podoba ci się [..] w wywołaniu funkcji, zawsze możesz iterować po obiekcie arguments.

+0

Ustawiam wartości słownikowe, takie jak zestaw ("dict_obj", [0, "Użytkownik"], 5). Ale nie mogę zwrócić wartości ustawionej przy użyciu połączenia typu "Console.log (" dict_obj [0] ['User']) Nie mogę zwrócić wartości 5. Czy widzisz jakikolwiek błąd z tym, jak tego używam? – ouonomos

+0

@ouonomos: Robisz to źle, ustawiasz wartość na ciągu '' dict_obj'' zamiast obiektu 'dict_obj'. – slebetman

+0

Przepraszam, źle wpisałem.To co aktualnie robię to: \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); gdzie dict_set jest funkcją autoviv. Ale console.log (lastposxns [0] ['abc']) nie zwraca wartości 5. – ouonomos

2

Czysto natywnie, nie sądzę. undefined nie jest rozszerzalny ani zmienny i jest to jedyny sposób, jaki mogłem sobie wyobrazić, nie wykonując go przez funkcję.

0

Lub możesz użyć rozwiązania opartego na eval. Jest brzydki, niezalecany.

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

Miałem chęć to zrobić, więc napisałem a package to handle it.

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

To będzie nawet zrobić tablicę z indeksami numerycznymi:

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

@ kodu slebetman za nie wydają się działać. Ostatni klucz nie powinien mieć przypisanego pustego obiektu, lecz raczej val. Ten kod zadziałał:

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

Cześć Mark, mam wątpliwości, czy istnieje jakaś dobra metoda przechwytywania zrzutu ekranu za pomocą kątowego js, ​​jeśli tak, możesz to sprawdzić https://stackoverflow.com/questions/44602309/making-a- poprawne przechwytywanie obrazu z ekranu przy użyciu jquery –