2

Let's say I have a complex object with properties that have properties.

var x = {};
x.A.B = 'Hello';
x.A.C = 'World!';
x.D.E = 100;
x.D.F = 2.5;

Is there anything I could put in a single set of square brackets in order to get back any of these properties? A simple test shows that x['A.B'] does not return 'Hello'. Is there any syntax for doing this?

Corey Ogburn
  • 24,072
  • 31
  • 113
  • 188
  • Yes, the syntax is to use more brackets or dot notation. – adeneo Feb 04 '14 at 22:12
  • x['A']['B'] should do the trick – Skwal Feb 04 '14 at 22:12
  • You should use x['A']['B'] or x.A.B – Goran.it Feb 04 '14 at 22:13
  • 1
    The situation is that I may not know exactly how many levels deep I'll need to go. I was hoping for a non-iterative way to do this. – Corey Ogburn Feb 04 '14 at 22:13
  • @CoreyOgburn you'll probably want to create a method that handles the randomness of your situation. e.g.: `deepProperyExists('a.b.c', obj)` Just iterate over the number of periods and checking if the property is undefined each iteration. (a, a.b, a.b.c) – Matt Lo Feb 04 '14 at 22:15
  • @MattLo I feel that may be the only way to do this. If nobody has a hack or trick for doing this directly, I may post my implementation of that as an answer. – Corey Ogburn Feb 04 '14 at 22:18
  • @CoreyOgburn I wrote something similar to this for namespace creation `NS('company.product.namespace')`, I guess an identical implementation could be used for verifying. https://github.com/mattlo/Namespace/blob/master/Namespace.js – Matt Lo Feb 04 '14 at 22:21

1 Answers1

2

If you don't want to iterate you could do it fairly safe with eval in strict mode. Not that I recommend doing this. But it's a way to do it.

var x = {A:{}};
x.A.B = 'Hello';

var propertyPath = 'A.B';
var value = eval('"use strict"; x.' + propertyPath);

console.log(value);

Another more reusable way would be to create a new Function object instead of using eval.

function propertyValue(obj, propertyPath) {
    'use strict';
    return (new Function('obj', 'return obj.' + propertyPath))(obj);
}

var value = propertyValue(x, 'A.B');

It is practically the same but has a clear definition.

Bart
  • 17,070
  • 5
  • 61
  • 80
  • 1
    I don't think eval is as evil as people try to say. As long as you never eval anything a user has given you. – Corey Ogburn Feb 04 '14 at 22:44
  • The situation I'm thinking about is for an internal work application where the `propertyPath` is coming from attributes on HTML controls that way the controls can indicate what properties their values will go in to (since we're not using any data binding library). They might be properties for properties. – Corey Ogburn Feb 04 '14 at 22:52
  • I updated my question with a more usable function you could use – Bart Feb 04 '14 at 23:25
  • Using info from [this question about dates](http://stackoverflow.com/questions/643782/how-to-know-if-an-object-is-a-date-or-not-with-javascript), [this question about escaping strings](http://stackoverflow.com/questions/770523/escaping-strings-in-javascript), [this question about testing for NaN](http://stackoverflow.com/questions/2652319/how-do-you-check-that-a-number-is-nan-in-javascript), and your answer above. I now have getter and setter functions that retains types. [JsFiddle for it](http://jsfiddle.net/coreyog/tQbNY/) – Corey Ogburn Feb 12 '14 at 21:11