diff --git a/optional-chaining.js b/optional-chaining.js new file mode 100644 index 00000000..f1811279 --- /dev/null +++ b/optional-chaining.js @@ -0,0 +1,12 @@ +"use strict"; + +var isValue = require("./object/is-value"); + +var slice = Array.prototype.slice; + +// eslint-disable-next-line no-unused-vars +module.exports = function (value, propertyName1 /*, …propertyNamen*/) { + var propertyNames = slice.call(arguments, 1), index = 0, length = propertyNames.length; + while (isValue(value) && index < length) value = value[propertyNames[index++]]; + return index === length ? value : undefined; +}; diff --git a/test/optional-chaining.js b/test/optional-chaining.js new file mode 100644 index 00000000..1f7d4056 --- /dev/null +++ b/test/optional-chaining.js @@ -0,0 +1,17 @@ +"use strict"; + +module.exports = function (t, a) { + var obj = { foo: { bar: "elo", par: null } }; + a(t(), undefined); + a(t(null), null); + a(t(obj), obj); + a(t(obj, "foo"), obj.foo); + a(t(obj, "foo", "bar"), "elo"); + a(t(obj, "foo", "bar", "slice"), String.prototype.slice); + a(t(obj, "foo", "par"), null); + a(t(obj, "foo", "par", "marko"), undefined); + a(t(obj, "marko"), undefined); + a(t(""), ""); + a(t("", "foo"), undefined); + a(t("", "slice"), String.prototype.slice); +};