A fully functional variant:
function traverse(tree, path, leftover) {
if (!tree || !path.length)
return leftover(path);
var ntree = {};
for (var p in tree)
ntree[p] = tree[p];
ntree[path[0]] = traverse(tree[path[0]], path.slice(1), leftover);
return ntree;
}
function create(path, value) {
if (!path.length)
return value;
var tree = {};
tree[path[0]] = create(path.slice(1), value);
return tree;
}
function set(tree, pathstring, value) {
return traverse(tree, pathstring.split("."), function(path) {
return create(path, value);
});
}
var seed = {a:{f:"whatever else"}};
var obj = set(seed, "a.b.c", "whatever")
// {"a":{"f":"whatever else","b":{"c":"whatever"}}}
set({}, "a.b.c", "whatever")
// {"a":{"b":{"c":"whatever"}}}