Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set object property (of object property of..) given its string name in JavaScript?

People also ask

Can an object property be a string?

Property keys must be strings or symbols (usually strings). Values can be of any type.

How do you set a property for an object?

After you have created an object, you can set or change its properties by calling the property directly with the dot operator (if the object inherits from IDL_Object) or by calling the object's SetProperty method.

How do you set an object property with variables?

Use computed property names to set an object's property name from a variable in TypeScript, e.g. const obj: Person = {[myVar]: 'Tom'} . The computed property names feature allows us to dynamically determine the property names of an object.


function assign(obj, prop, value) {
    if (typeof prop === "string")
        prop = prop.split(".");

    if (prop.length > 1) {
        var e = prop.shift();
        assign(obj[e] =
                 Object.prototype.toString.call(obj[e]) === "[object Object]"
                 ? obj[e]
                 : {},
               prop,
               value);
    } else
        obj[prop[0]] = value;
}

var obj = {},
    propName = "foo.bar.foobar";

assign(obj, propName, "Value");

Since this question appears to be answered by incorrect answers, I'll just refer to the correct answer from a similar question

function setDeepValue(obj, value, path) {
    if (typeof path === "string") {
        var path = path.split('.');
    }

    if(path.length > 1){
        var p=path.shift();
        if(obj[p]==null || typeof obj[p]!== 'object'){
             obj[p] = {};
        }
        setDeepValue(obj[p], value, path);
    }else{
        obj[path[0]] = value;
    }
}

Use:

var obj = {};
setDeepValue(obj, 'Hello World', 'foo.bar.foobar');

I know it's an old one, but I see only custom functions in answers.
If you don't mind using a library, look at lodash _.set and _.get function.


edit: I've created a jsPerf.com testcase to compare the accepted answer with my version. Turns out that my version is faster, especially when you go very deep.

http://jsfiddle.net/9YMm8/

var nestedObjectAssignmentFor = function(obj, propString, value) {
    var propNames = propString.split('.'),
        propLength = propNames.length-1,
        tmpObj = obj;

    for (var i = 0; i <= propLength ; i++) {
        tmpObj = tmpObj[propNames[i]] = i !== propLength ?  {} : value;  
    }
    return obj;
}

var obj = nestedObjectAssignment({},"foo.bar.foobar","hello world");