Я делаю небольшой проект и инициализирую объект множеством свойств и методов, некоторые из которых будут ссылаться на объект самостоятельно, чтобы получить какое-то другое свойство (в настоящее время у меня есть только один такой). Поскольку я не могу получить доступ к другим свойствам объекта во время инициализации, я решил заменить самоссылающиеся свойства в функциях, называемых init, которые возвращают undefined, если одно из необходимых свойств не определено. Это то, что у меня есть в настоящее время (я собираюсь проверить, существует ли gameTemplates, а затем заменить его на функцию):
generateCorrectGuess: function init() {
if (gameTemplates.numberOfElements === undefined || (gameTemplates.numberOfElements instanceof Function && gameTemplates.numberOfElements.name === "init")) {
return undefined;
}
return GenerateArray.generateRandomNumsNonRepeating.bind(undefined, gameTemplates.numberOfElements)
}
Позже у меня есть функция init, которая получает все функции init и затем инициализирует их. Проблема в том, что я не смог придумать способ сделать while l oop декларативным способом и просто сделал функцию repeatWhile, которая использует while l oop. Проблема в том, что для того, чтобы отделить чистую функцию и функцию, которая изменяет состояние объекта в дополнение к наличию отдельного входа для проверки. Это заставляет функцию repeatWhile принимать 5 аргументов, а чистая функция имеет присваивание и более сложный вывод. Есть ли у вас какие-либо идеи, чтобы сделать код более простым и пригодным для повторного использования? Спасибо.
Вот код:
function init(obj) {
function getInitArr(obj) {//this function works and does not seem to need checking
function getModifiedArray(prop) {
function getTypeOfProp(prop) {
return [
function object(prop) {return typeof prop === "object" && prop.genObj === 0},
function initFunction(prop) {return prop instanceof Function && prop.name === "init"},
function normal() {return true}
]
.find(a=>a(prop)).name;
}
const getModifiedArrayByType = {
object: function (prop) {
return getInitArr(obj[prop])
},
initFunction: function (prop) {
return [[obj, prop, obj[prop]]]
},
normal: function () {
return []
}
};
return getModifiedArrayByType[getTypeOfProp(obj[prop])](prop);
}
return Object.keys(obj)
.reduce((arr,prop)=>[...arr, ...getModifiedArray(prop)], [])
}
function initProperties() {
const getIndicesIfNotUndefined = (a, objPropFn, i) => {
if (objPropFn[2]() !== undefined) {
return [...a, i];
}
return a;
};
function getAllExceptResetOnes(toCheck) {
return (a, i) => !(toCheck.includes(i));
}
return function (input) {
let toCheck = input
.reduce(getIndicesIfNotUndefined, []);
return [
input.filter(getAllExceptResetOnes(toCheck)),
// toCheck
// .reduce((acc, index) => {
// acc.splice(acc[acc.length - 1], 1, ...input.slice(acc[acc.length - 1] + 1, index));
// return acc;
// }, []),
toCheck,
[input, toCheck]
]
};
}
function initializeProperties([input, toCheck]) {
toCheck
.forEach(index => {
input[index][0][input[index][1]] = input[index][2]();
});
}
repeatWhile(
initProperties(),
resToCheck=>resToCheck.length>0,
getInitArr(obj),
initializeProperties
);
function repeatWhile (fn, condition, input, actionOnSeparateOutput = x=>x, inputToCheck = input) {
let separateOutput;
while (condition(inputToCheck)) {
[input, inputToCheck = input, separateOutput = input] = fn(input);
actionOnSeparateOutput(separateOutput);
}
return input;
}
}