#javascript #ecmascript-6
#javascript #ecmascript-6
Вопрос:
например, я определяю объект obj
:
var obj = {}
Object.defineProperty(obj, "a", {
value : 37,
writable : true,
enumerable : true,
configurable : true
});
console.log(obj.a); // => 37
Я хочу получить доступ ко всем неизвестным дочерним элементам с одинаковым значением, например obj.a.b.c.d.e
/ obj.c.d.e.f.e....
=> 37
Комментарии:
1. Если
obj.a
должно быть 37, тоobj.a.b
должно быть37.b
значение, которое не определено…
Ответ №1:
Нет способа вернуть такое число, потому что каждое вложенное свойство должно возвращать объект, если вы хотите иметь неограниченный доступ к другим вложенным ключам — лучшее, что вы можете сделать, это вернуть объект, который может быть преобразован в желаемую строку, возможно, с помощью прокси:
const handler = {
get(_, prop) {
return prop === Symbol['toPrimitive']
? () => '37'
: objProx;
}
}
const objProx = new Proxy({}, handler);
console.log('' objProx.a); // => '37'
console.log('' objProx.a.b); // => '37'
console.log('' objProx.a.b.c.d.e.foobarbaz); // => '37'
Ответ №2:
Вы могли бы создать функцию, которая принимает другую функцию в качестве параметра. И выполнить функцию внутри try...catch
и вернуть значение, если оно существует, или вернуть значение по умолчанию, если произошла ошибка:
const DEFAULT_VAL = 37;
// get a function and an optional default value to override
function getAnyDepth(func, def) {
try {
return func();
} catch (e) {
return typeof def !== "undefined" ? def : DEFAULT_VAL;
}
}
var obj = { a: 45 }
console.log(getAnyDepth(() => obj.a))
console.log(getAnyDepth(() => obj.a.b.c.d.e))
console.log(getAnyDepth(() => obj.c.d.e, { b: 100 }))
Ссылка: Как избежать «Не удается прочитать ‘name’ свойства undefined» в JavaScript
Ответ №3:
Если вы имеете в виду, что вам нужно значение по умолчанию каждый раз, когда вы обращаетесь к неопределенному ключу в вашем объекте, вы должны :
_.defaults(obj, {value: 37"})
или вы можете использовать стандартное сравнение :
if(typeof obj.a =='undefined'){
return 37
}
Ответ №4:
Если obj.a
равно 37, то obj.a.b
будет вычисляться значение 37.b
, которое не определено. Однако, если вас устроит, если 37 будет результатом преобразования чего-либо в примитив (например, путем конкатенации строк), тогда вы могли бы создать прокси.
ДЕМОНСТРАЦИЯ:
// Preparation
function setDefaultProperty(obj, defProp) {
return new Proxy(obj, {
get(target, prop) {
if (prop in target || typeof prop === "symbol") return target[prop];
return target[defProp];
}
});
}
var sink = setDefaultProperty({}, "_default");
sink._default = sink;
sink.valueOf = () => 37;
// Demo
var obj = {};
obj = setDefaultProperty(obj, "_default");
obj._default = sink;
console.log("" obj.a.b.c.e); // 37
console.log("" obj.what.ever); // 37