I was surprised not to find this useful feature in the Javascipt base interface. The following is a helper function that I often use in my projects. It checks whether the value of the final element of the chain is reachable without the error "it is impossible to get ... from undefined":
getChained: function (
chainScope,
chain,
functionsParameters) {
var parts;
var part;
var partIndex;
var target = undefined;
var functionIndex = 0;
if (
chainScope === undefined ||
chainScope === null) {
return target;
}
target = chainScope;
parts = getParts();
for (
partIndex = 0;
partIndex < parts.length;
partIndex++) {
if (target === undefined) {
return undefined;
}
part = parts[partIndex];
if (
part.indexOf("(") >
part.indexOf("\"") &&
part.indexOf("(") >
part.indexOf("\'")) {
target = getFunctionValue();
functionIndex++;
continue;
}
if (
part.indexOf("[") >
part.indexOf("\"") &&
part.indexOf("]") >
part.indexOf("\'")) {
target = getArrayValue();
continue;
}
if (
typeof part === "string" &&
target !== null &&
target !== undefined) {
target = target[part];
continue;
}
}
return target;
function getParts() {
var SEPARATOR = ".";
var OPEN_CHARS = [
"(",
"[",
"\"",
"\'"
];
var CLOSE_CHARS = [
")",
"]",
"\"",
"\'"
];
var SUB_SEPARATOR_OPEN = "[";
var SUB_SEPARATOR_CLOSE = "]";
return(
splitBySubSeparator(
splitBySeparator(
chain)));
function splitBySeparator(chainString) {
var parts = [
];
var opened = 0;
var char1;
var chainIndex;
var extract;
var cutFromIndex = 0;
var chainArray;
chainArray =
(chainString + ".").
split("");
for (
chainIndex = 0;
chainIndex < chainArray.length;
chainIndex++) {
char1 = chainArray[chainIndex];
if (OPEN_CHARS.indexOf(char1) > 0) {
opened++;
continue;
}
if (CLOSE_CHARS.indexOf(char1) > 0) {
opened--;
continue;
}
if (opened === 0) {
if (char1 === SEPARATOR) {
extract =
chainArray.slice(
cutFromIndex,
chainIndex).
join("");
parts.push(
extract);
cutFromIndex = chainIndex + 1;
} else {
continue;
}
}
}
return parts;
}
function splitBySubSeparator(parts) {
var newParts = [
];
var opened = 0;
var char1;
var partIndex;
var chainIndex;
var chainArray;
for (
partIndex = 0;
partIndex < parts.length;
partIndex++) {
var part = parts[partIndex];
chainArray = part.split("");
for (
chainIndex = 0;
chainIndex < chainArray.length;
chainIndex++) {
char1 = chainArray[chainIndex];
if (
opened === 0 &&
char1 === SUB_SEPARATOR_OPEN) {
part =
part.substr(0, chainIndex) +
SEPARATOR +
part.substr(chainIndex + 1);
opened++;
}
if (
opened > 0 &&
char1 === SUB_SEPARATOR_CLOSE) {
part =
part.substr(0, chainIndex) +
"" +
part.substr(chainIndex + 1);
opened--;
}
}
newParts =
newParts.concat(
splitBySeparator(part));
}
return newParts;
}
}
function getFunctionValue() {
var value;
var name;
name =
part.
split("(")[0];
if (functionsParameters) {
value =
target[name].
apply(
target,
functionsParameters[
functionIndex
]);
} else {
value =
target[name].
apply(
target);
}
return value;
}
function getArrayValue() {
var value;
var arrayName;
var itemName;
arrayName =
part.
split("[")[0];
itemName =
(part.
split("[")[1].
split("]")[0]).
split("\'").
join("").
split("\"").
join("");
if (target[arrayName]) {
value =
target[arrayName][itemName];
}
return value;
}
}
source
share