我在Javascript中有许多子属性和对象的对象。
因此我的代码中的某些行看起来像这样:
obj.eventOfType = (el.openSocial && el.openSocial.embed && el.openSocial.embed.context &&
el.openSocial.embed.context.openSocial && el.openSocial.embed.context.openSocial.connections &&
el.openSocial.embed.context.openSocial.connections.generator && el.openSocial.embed.context.openSocial.connections.generator.displayName) ?
el.openSocial.embed.context.openSocial.connections.generator && el.openSocial.embed.context.openSocial.connections.generator.displayName || "";
看起来不太好..所以我想到了一个函数并写了这个:
/**
* assert path exists as subobject chain within obj
*
* @param obj {object} the object to search for <code>path</code> in
* @param path {String} the path to search within <code>obj</code>. oatgh must not start wirth the object itself.
* @return {boolean} whether <code>path</code> exists within <code>obj</code> or not
* example: to check if the windows document body has a fist item element you would use
* if (assertChain(window, "document.body.firstChild")) {}
* instead of
* if (window && window.document && window.document.body && window.document.body.firstChild) {}
*/
function assertChain(obj, path) {
var o = obj,
ret = ("object" === $.type(obj) && "string" === $.type(path));
if (ret) {
$(path.split(".") || {}).each(function(ignore, value) {
ret = value in o;
if (ret) {
o = o[value];
}
return ret;
});
}
return ret;
}
var t = assertChain(dataItem, "dataItem.openSocial.embed.context.connectionsContentUrl") && dataItem.openSocial.embed.context.connectionsContentUrl;
dataItem.xcc = dataItem.xcc || {}; //Access it
所以在Stackoverflow,我发现了这个:
var isDefined = function(value, path) {
path.split('.').forEach(function(key) { value = value && value[key]; });
return (typeof value != 'undefined' && value !== null);
};
var t = {a: {a1: 33, a12: {aa1d: 444, cc: 3}}, b: 00};
var results = '';
['a.a12.cc', 'a.a1.cc'].forEach(function(path) {
results += 't[' + path + '] = ' + isDefined(t, path) + '\n';
});
document.body.appendChild(document.createElement('pre')).textContent = results;
哪种方式最好?