0

Suppose we're given a javascript object

var json = {
  abc: 1,
  def: 2,
  ghi: [3, 4]
};

And we'd like to access its members, for instance given the following string array

var str_arr = ["json['abc']", "json['ghi'][1]"];

I want to get the following result without using eval (I'm building a Google Chrome extension)

var str_res = [1, 4];

Would this be possible? I tried doing window, but it doesn't work (or probably I don't know how). Thanks!

Ivan Wangsa
  • 209
  • 2
  • 9
  • 2
    That isn't json. Json is not an object. That is a javascript object. Json is a **string notation** (JavaScript Object Notation). i.e. it's a string representation of a javascript object. "{ abc: 1, def: 2, ghi: [3, 4] }" would be Json, not what you have, aggghhhhh – Liam Dec 08 '15 at 10:14
  • Thanks @Liam. Changed the question. – Ivan Wangsa Dec 08 '15 at 10:18
  • 1
    Thank you, I'm going to lie down in a cool room – Liam Dec 08 '15 at 10:20
  • @IvanWangsa I use eval in my answer and it is working – Omar Mowafi Dec 08 '15 at 10:22

3 Answers3

2

I don't recommend iterating through the entire object using custom methods, but if you really can't access the object directly, you can use a recursive function and pass the keys you want to open. This might give you a bit more of the dynamic feeling you want.

Code:

function readObjectValue(obj, key, defaultValue) {
    function __readObjectValueInternal(obj, keyParts, defaultValue) {
        if (!obj.hasOwnProperty(keyParts[0])) {
            return defaultValue;
        }

        var readValue = obj[keyParts[0]];

        if (typeof(readValue) !== 'object') {
            return readValue;
        }

        return __readObjectValueInternal(readValue, keyParts.slice(1), defaultValue);
    };

    return __readObjectValueInternal(
        obj, 
        (typeof(key) === 'string' ? key.split(/\./g) : key), 
        defaultValue
    );
}

Usage:

var json = {
  abc: 1,
  def: 2,
  ghi: [3, 4]
};

console.log( readObjectValue(json, 'abc')            ); // 1
console.log( readObjectValue(json, 'ghi.1')          ); // 4
console.log( readObjectValue(json, 'ghi.2')          ); // undefined
console.log( readObjectValue(json, 'ghi.3', null)    ); // null
console.log( readObjectValue(json, ['def', 0], null) ); // 2
h2ooooooo
  • 39,111
  • 8
  • 68
  • 102
  • This is what I need. Thanks @h2ooooooo! I'm using it for internal purposes, so I guess there shouldn't be no harm - but why is this not a best practice? – Ivan Wangsa Dec 08 '15 at 10:41
  • @IvanWangsa Because it can't optimize the code as well when we're using our own method of doing something. If we used internal JS methods we'd be able to take advantage of already optimized code. No need to reinvent the wheel if you can use something build-in. That said, if this is a chrome addon that uses V8 it should not be an issue. You can always benchmark it, if you figure it necessary. You may also hit a stack overflow if you try to read more than X sub-keys, but [the stack size is so large that it should never happen™](http://stackoverflow.com/a/7828803/247893). – h2ooooooo Dec 08 '15 at 10:56
1

You can achieve what you are asking for using this loop

str_arr.forEach(function(string,index){
  str_arr[index] = window.eval(string);
});
console.log(str_arr);
Omar Mowafi
  • 854
  • 5
  • 13
  • Hey @Omar Mowafi, it works! But I just realized I forgot to add the fact that I can't use eval - I'm building a Chrome extension. So sorry! :( – Ivan Wangsa Dec 08 '15 at 10:23
  • It still doesn't work, unfortunately. Google Chrome is strict when it comes to eval I guess. – Ivan Wangsa Dec 08 '15 at 10:32
0

You can try this

var str_arr = [
(json['abc'])?json['abc']:undefined,
(json['ghi'][1])?json['ghi'][1]:undefined
]; 
Suraj Rawat
  • 3,685
  • 22
  • 33
  • This would give an error if the `ghi` key didn't exist (not undefined like you think). You need to use `json['ghi'] && json['ghi'][1]` to not throw an error. – h2ooooooo Dec 08 '15 at 10:21
  • what ever there might be 3 dimensional array also it was just a snippet for the solution rest what ever you want , thanks for mentioning it appreciated ! – Suraj Rawat Dec 08 '15 at 10:23