Использование чистой функции с объектом Javascript - PullRequest
4 голосов
/ 22 октября 2019

Предположим, у меня есть такой код:

function example() {
  const obj = {};
  for (let i = 0; i < 10; i++) {
    for (let j = 0; j< 10; j++) {
       if (obj[i] == undefined) {
         obj[i] = 0;
       }
       if (obj[j] == undefined) {
         obj[j] = 0;
       } else {
         obj[i] += i;
         obj[j] += j;
       }
    }
  }
}

Здесь вы можете увидеть:

if (obj[i] == undefined) {
  obj[i] = 0;
}

Я проверяю, нет ли i в obj Я назначаю ключ i внутри obj с 0, иначе я ничего не делаю, я делаю выборку с j.

Код дублируется, и я не хочу повторяться, это плохая практика, поэтому я выполняю другую функциюподать заявку на i и j вот так:

function initObjWithValue(obj, keys) {
  for (const key of keys) {
    if (obj[key] === undefined) {
      obj[key] = 0;
    }
  }
}

Функция очень проста для понимания, верно? Он имеет первый параметр в качестве объекта, а второй параметр представляет собой массив ключей для проверки. Теперь я могу изменить свой код следующим образом:

function example() {
  const obj = {};
  for (let i = 0; i < 10; i++) {
    for (let j = 0; j< 10; j++) {
       initObjWithValue(obj, [i, j]);
       obj[i] += i;
       obj[j] += j;
    }
  }
}

Код более понятен, но, как вы можете видеть в моей функции initObjWithValue, он мутирует obj, и я думаю, что это не хорошо. Вот цитата со страницы Wiki:

В компьютерном программировании чистая функция - это функция, имеющая следующие свойства: ее возвращаемое значение одинаково для тех же аргументов (без изменений с локальными статическими переменными, нелокальные переменные, изменяемые ссылочные аргументы или входные потоки от устройств ввода-вывода).

И я застрял в этой точке, как я не могу повторить себяи я могу добиться чистой функции в этом случае?

Ответы [ 2 ]

3 голосов
/ 22 октября 2019

Вместо этого вы можете initObjectWithValue вернуть новый объект, который затем можете объединить с вашим текущим obj. Таким образом, все, что вы делаете, это читаете из obj, а не изменяете его в initObjectWithValue:

function initObjWithValue(obj, keys) {
  const tmp = {};
  for (const key of keys) {
    if (!(key in obj)) {
      tmp[key] = 0;
    }
  }
  return tmp;
}

function example() {
  const obj = {};
  for (let i = 0; i < 10; i++) {
    for (let j = 0; j< 10; j++) {
       Object.assign(obj, initObjWithValue(obj, [i, j])); // merge the return with current object
       obj[i] += i;
       obj[j] += j;
    }
  }
  return obj;
}

console.log(example());
0 голосов
/ 22 октября 2019

Вместо проверки

(obj[i] == undefined)

запись

(typeof obj[i] == undefined)
...