I need to use prompt (class assignment) to allow the user to input an
object name. The problem is obj returns as a string
How can I cast the value from the prompt to an object?
You can't since Objects don't have names. You can have either variables or object properties whose value is a reference to an object though:
var obj = {};
creates a variable whose name is obj and whose value is a reference to an object.
If you want to dynamically create variables, you can use eval, but it's not recommended. It is very much warned against to use eval to execute random code entered by users since they are completely unaware of the variables that already exist and that you don't want them to mess with.
What you can do is create an object specifically to add properties to, since almost any string value can be used as a property name. So you might do:
function enumObject(){
// markup and div will be used later
var markup = '';
var div;
// Here's where the property names will be stored
var obj = {};
var propertyName = prompt("Please enter an object name", "window.navigator");
obj[propertyName] = {};
// This is redundant since an object was just assigned so it will
// always return true
if (typeof obj[propertyName] == "object") {
// Always perform a hasOwnProperty check so you don't get
// inherited properties, you only want the ones added by the user
// Also, don't re-used variables, create a new one
for (var prop in obj) {
if (obj.hasOwnProperty(prop)) {
// Don't use document.write after the page has finished loading
// as it will clear the entire document first before writing
markup += propertyName + " : " + obj[propertyName] + "<br>";
}
}
// This should never execute since the test should always be true
} else {
alert('The object name is undefined.');
}
// Write to the document without destroying it
div = document.createElement('div');
div.innerHTML = markup;
document.body.appendChild(div);
}
Edit
Maybe you want to access object properties based on user defined strings. In that case, you can do something like the following. It only uses eval if the root of the property accessor is not window and only strings that appear to be valid identifiers, not random code:
// Assumes dot notation like window.navigator or foo.bar
function getObjectValueByString(s) {
var identifier, path = [];
// Very simple identifier re
var identifierRe = /^[_$a-z][a-z0-9_$]*$/i;
s = s.split('.');
// Loop over parts of s
for (var i=0, iLen=s.length; i<iLen; i++) {
identifier = s[i];
path.push(identifier);
if (identifierRe.test(identifier)) {
// Get root of accessor
if (i == 0) {
if (identifier == 'window') {
obj = window;
// Only use eval on what appear to be valid identifiers
// not arbitrary code
} else {
obj = eval(identifier);
}
// If not root, get property value
} else {
obj = obj[identifier];
}
// Stop if obj isn't an object
if (typeof obj != 'object') {
// Message if didn't get to end of accessor
if (i < iLen - 1) {
return 'Stopped at ' + path.join('.') + ' = ' + obj;
}
}
} else {
return identifier + ' is not a valid identifier';
}
}
return path.join('.') + ' = ' + obj;
}
To play with it:
<input onblur="console.log(getObjectValueByString(this.value));">
A much more rigorous regular expression for identifier names that excludes reserved words is in the accepted answer for Valid Characters for JavaScript Variable Names.
If only properties of window are required, life becomes much simpler and eval is not needed at all, so nor is the regular expression to check for valid identifiers:
function getWindowValueByString(s) {
var identifier, path = [];
var obj = window;
s = s.split('.');
// Loop over parts of s
for (var i=0, iLen=s.length; i<iLen; i++) {
identifier = s[i];
path.push(identifier);
// Check only using window
if (i == 0) {
if (identifier != 'window') {
return 'Only valid for properties of window';
}
} else {
obj = obj[identifier];
}
// Stop if obj isn't an object
if (typeof obj != 'object') {
// Message if didn't get to end of accessor
if (i < iLen - 1) {
return 'Stopped at ' + path.join('.') + ' = ' + obj;
}
}
}
return path.join('.') + ' = ' + obj;
}