2

Not sure if this can even be done, but I'll ask anyway:

Suppose if I have an array of names:

['bob', 'sue', 'dan']

And I want to dynamically create an object from those names:

bob.sue.dan = 5;

Is it possible?

5 Answers 5

3

Here you go, will preserve existing objects:

var namespace = function(name, separator, container){
  var ns = name.split(separator || '.'),
    o = container || window,
    i,
    len;
  for(i = 0, len = ns.length; i < len; i++){
    o = o[ns[i]] = o[ns[i]] || {};
  }
  return o;
};

e.g. usage:

namespace("com.example.namespace");
com.example.namespace.test = function(){
  alert("In namespaced function.");
};

or for your example using an array.

var ns = ['bob', 'sue', 'dan'];
namespace(ns.join('.'));
bob.sue.dan.foobar = true;

or extending an existing object:

var bob = {}
namespace("foo.bar",".",bob);
bob.foo.bar = true;

Edit: updated as requested:

var namespace = function(name, separator, container, val){
  var ns = name.split(separator || '.'),
    o = container || window, i, len;
  for(i = 0, len = ns.length; i < len; i++){
      var v = (i==len-1 && val) ? val : {};
      o = o[ns[i]] = o[ns[i]] || v;
  }
  return o;
};

namespace("bob.sue.dan",null,null,5);
alert(bob.sue.dan);

See working example: http://jsfiddle.net/herostwist/hu6j9/

Sign up to request clarification or add additional context in comments.

4 Comments

I like the elegance of your solution a lot. Is there a way to edit it to give a value in the function itself?
for example: namespace(name, seperator, container, value)
thank you. Not 100% sure how it works, but it does and does well.
Maybe too late comment but in case of using this method in WebWorker we need to change a bit the function related to the container. Remove the window from the || statement and add the below lines if (typeof window != "undefined") { o = window; } else if (typeof self != "undefined") { o = self; }
2

Then you can do:

function makeOjectTree(propNames) {
  var name;
  var o = {};
  var result = o;

  for (var i=0, iLen=propNames.length; i<iLen; i++) {
    name = propNames[i];

    if (!o[name]) {
      o[name] = {};
      o = o[name];
    }
  }
  return result;
}

Comments

2
var names = ['bob', 'sue', 'dan'];
var objs = [];

for(var i=0; i<names.length; i++) {
  objs.push(names[i]);
  var val = (i==names.length-1) ? "5" : "{}";
  eval(objs.join(".") + " = " + val);
}

alert(bob.sue.dan);

Demo: http://jsfiddle.net/EpZm2/1/

Comments

1

sure you can ...

var obj = 5;
var yourarray = ['bob', 'sue', 'dan'];

yourarray = yourarray.reverse();
for(e in yourarray) {
    var tmpobj = obj;
    obj = new Object();
    obj[yourarray[e]] = tmpobj;

    // if you already have an object
    if (e+1 == yourarray.length) {
        your_current_existing_object[yourarray[e]] = tmpobj;
    }
}

2 Comments

What would happen if I already had an object with some populated properties?
Don't use for..in with arrays unless there is a very good reason and you have protected against the foibles.
-2

Yes this is possible.

You can define new properties on an object this way:

var obj = {};
obj["bob"] = {};
obj["bob"]["sue"] = {};
obj["bob"]["sue"]["dan"] = 5;

So you can also do it with an array of property names ;)

3 Comments

that's not dynamically created object
especially since I don't want to disturb any other properties that are already in other levels of the structure
@Teneff I never said it is a dynamically created object. I only showed you the way you could define properties dynamically by a string. And that´s exactly what you need ;) I think -1 is not fair...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.