Basically, I have a bunch of input rows, each with id in the form
of something like.. item:characteristics:age or item:setting:type1:blah. It's kind of like going down folders to get to the item I want. So as you can see in the code, I am splitting each id and trying to rebuild it in the form item[characteristics][age] then set it to the value of the input field. This is modifying the properties of the item. We already have the item object passed into my code and i'm simply modifying the properties to the new values from the user's input.

Does anyone know how I can do this without eval?
I'm mainly using it because the variable name can't be hard coded, it is dynamic.

Here's the code I have so far.

jQuery('#debugWidget .edit').each(function() {

     var id = "";          
     var ids = this.id.split(':');

     for (i in ids) {
            if(i==0) {
                id += ids[i];
                continue;
           }
            id += "['"+ids[i]+"']";
     }

eval(id+" = '"+jQuery(this).val()+"';");

Thanks JS gurus.

CrimsonD,

You can do this either recursively or iteratively. Here is an iterative solution, which is by far the simpler of the two.

var propIterator = function(obj, propsStr){
	if(!obj) { return null; }
	if(obj && typeof obj === 'object' && propsStr && typeof propsStr === 'string') {
		var propsArray = propsStr.split(':');
		for(var i=0; i<propsArray.length; i++){
			var obj = obj[propsArray[i]];
			if(typeof obj != 'object') { break; }
		}
	}
	return obj;
};

var testObj = {};
testObj.a = {};
testObj.a.b = {};
testObj.a.b.c = 'Hello World!';

alert( propIterator(testObj, 'a:b:c') );

A nice feature is that the function is pretty error tollerant. It stops trying to iterate of it reaches a non object. So if you were to try propIterator(testObj, 'a:b:c:d:e') , then you would still get Hello World!, not an error. And if you were to specify a property that doesn't exist, that's handled too. propIterator(testObj, 'a:b:z') , would give "undefined" not an error.

Airshow

Even better, make it a method of every Object.

Object.prototype.propIterator = function(propStr){
	obj = this;
	if(propStr && typeof propStr === 'string') {
		var propArray = propStr.split(':');
		for(var i=0; i<propArray.length; i++){
			var obj = obj[propArray[i]];
			if(typeof obj != 'object') { break; }
		}
	}
	return obj;
};

var testObj = {};
testObj.a = {};
testObj.a.b = {};
testObj.a.b.c = 'Hello World!';

alert( testObj.propIterator('a:b:c') );

Airshow

And here's the recursive version with a bunch of test cases - not as messy as I expected.

var testObj = {};
testObj.a = {};
testObj.a.b = {};
testObj.a.b.c = 'Hello World!';

Object.prototype.propDriller = function(props){
	props = (!props || !props.length) ? [] : props;
	if(typeof props == 'string') props = props.split(':');
	if(props.length == 0) { return this; }
	var o = props.shift();
	if(typeof this[o] == 'object') { return this[o].propDriller(props); }
	else { return this[o]; }
}
alert( testObj.propDriller('a:b:c') );//retuns "Hello World!"
alert( testObj.propDriller('a:b:c:d:e') );//retuns  "Hello World!"
alert( testObj.propDriller({}) );//retuns testObject 
alert( testObj.propDriller([]) );//retuns testObject
alert( testObj.propDriller('') );//retuns testObject
alert( testObj.propDriller() );//retuns testObject
alert( testObj.propDriller('z') );//retuns "undefined"
alert( testObj.propDriller('a:b:z') );//retuns "undefined"

Tested in IE6 and Netscape 4.73!!

Airshow

This article has been dead for over six months. Start a new discussion instead.