#javascript #object #functional-programming
Вопрос:
У меня есть два входа:
data = {"year": 2021}
valueAccessor = (d) => d["year"];
Эти два ввода могут быть динамическими, поэтому я не знаю, что будет в объекте или функции.
Я хочу создать новый объект и задать значения для этого объекта с помощью функции доступа. Есть ли способ сделать это?
output = {}
output = definePropertyUsingFunction(output, valueAccessor, newValue)
Комментарии:
1. Нет, это не так…
Ответ №1:
Короткий ответ — «нет». Но…
Если вы находитесь в какой-то контролируемой среде обучения, есть некоторые вещи, которые вы могли бы попробовать.
Если вы точно знаете, что:
- Ваша
getter
функция чиста (без побочных эффектов), и - Ваша
getter
функция всегда обращается к 1 свойству,
ты мог бы
- Используйте
Proxy
функцию, которая отслеживает доступ к свойствам - Сделайте вызов
getter
, чтобы вызвать его (опять же, если это чистая функция, она не должна иметь никаких побочных эффектов). - Запишите значение в зарегистрированное свойство
Вот доказательство концепции:
const data = { year: 2000, month: 1, day: 28 };
const getYear = obj => obj.year;
const getMonth = obj => obj.month;
const toString = obj => `${obj.year}/${obj.month}/${obj.day}`;
const writeViaSimpleGetter = (obj, value, getter) => {
let propName = null;
const proxy = new Proxy(obj, {
get: (target, key) => {
if (propName) throw "Multiple properties accessed";
propName = key;
}
});
// Call the getter
getter(proxy);
if (!propName) throw "No property accessed";
return { ...obj, [propName]: value };
}
// Simple getters work:
console.log(
writeViaSimpleGetter(data, 2021, getYear)
)
console.log(
writeViaSimpleGetter(data, 12, getMonth)
)
// This throws:
try {
console.log(
writeViaSimpleGetter(data, "oops", toString)
)
} catch(e) { console.log("ERROR:", e) }
// This also throws:
try {
console.log(
writeViaSimpleGetter(data, "oops", () => {})
)
} catch(e) { console.log("ERROR:", e) }