What is the best way to have js return undefined rather than throw an error when a parent property does not exist?
Example
a = {}
b = a.x.y.z
// Error: Cannot read property 'value' of undefined
// Target result: b = undefined
What is the best way to have js return undefined rather than throw an error when a parent property does not exist?
Example
a = {}
b = a.x.y.z
// Error: Cannot read property 'value' of undefined
// Target result: b = undefined
Share
Improve this question
asked Jun 7, 2012 at 17:05
arcyqwertyarcyqwerty
10.7k4 gold badges52 silver badges89 bronze badges
1
-
If you don't want to fill your code with a lot of
try
/catch
(that is somehow a solution), in JS usually you check if an object is defined before using a specific property / method of it. It means, in that case, that you should verify thata
hasx
, before access to it, and so on. If you using that approach to simulate namespaces, you can create your own function that do this operation recursively for you. – ZER0 Commented Jun 7, 2012 at 17:11
4 Answers
Reset to default 3You have to check for the existence of each property:
var b;
if (a.x && a.x.y && a.x.y.z) {
b = a.x.y.z
}
Or, simliar to another poster's "safeGet" function:
var get = function (obj, ns) {
var y = ns.split('.');
for(var i = 0; i < y.length; i += 1) {
if (obj[y[i]]) {
obj = obj[y[i]];
} else {
return;
}
}
return obj;
};
Use:
var b = get(a, 'x.y.z');
try {
a = {}
b = a.x.y.z
}
catch (e) {
b = void 0;
}
I would go for slightly verbose:
var b = ((a.x || {}).y || {}).z
you could write a safeGet
helper function, something like:
edited for drilldown as suggested in ments by arcyqwerty
var getter = function (collection, key) {
if (collection.hasOwnProperty(key)) {
return collection[key];
} else {
return undefined;
}
};
var drillDown = function (keys, currentIndex, collection) {
var max = keys.length - 1;
var key = keys[currentIndex];
if (typeof collection === 'undefined') {
return undefined;
}
if (currentIndex === max) {
return getter(collection, key);
} else {
return drillDown(keys, currentIndex + 1,
getter(collection, key));
}
};
var safeGet = function (collection, key) {
if (key.indexOf(".") !== -1) {
return drillDown(key.split("."), 0, collection);
} else {
return getter(collection, key);
}
};
a = { x: 1 };
b = safeGet(a, 'x.y.z');
http://jsfiddle/YqdWH/2/