Функциональное программирование JavaScript, глубокое понимание чистых функций

внешний интерфейс GitHub JavaScript функциональное программирование

Смотрите блог для более связанного контентаGitHub.com/dedicated мойка…

Чистые функции являются основой функционального программирования и требуют глубокого понимания. Роль чистых функций вы можете увидеть«Почему функциональное программирование в JavaScript функциональное программирование (нестрогая техническая чушь)».

Понятие чистой функции:

Чистая функция — это функция, т. е. одни и те же входные данные всегда будут иметь одинаковый результат и не будут иметь наблюдаемых побочных эффектов.

егоСуть в том, что «один и тот же ввод — всегда один и тот же вывод»., побочные эффекты, упомянутые позже, также должны удовлетворять этому пункту.

Прежде чем подробно описывать чистые функции, давайте поговорим о двух других понятиях:Изменяемые и неизменяемые типы данных.

Мы знаем, что в JavaScript основные типы данных неизменяемы.Их можно только заменить, но не модифицировать.. Например, когда мы работаем со строкой, мы не можем изменить саму строку.

var str = 'I am hero';
console.log(str.toUpperCase());	// "I AM HERO"
console.log(str);	//"I am hero"

Все, что мы можем сделать, это переназначить возвращенную новую строку переменной.

var str = 'I am hero';
str = str.toUpperCase();	// "I AM HERO"

Все ссылочные типы данных изменяемы, и единственное, что существует в переменной, — это адрес. Что касается изменяемых функций, в immutable.js Facebook были внесены целевые улучшения, и есть более тщательные методы, такие как clojurescript.

Зачем говорить об этих двух понятиях?

Не говоря уже о том, что могут быть побочные эффекты в системной среде, в которой работает JS. Простой взгляд на эти переменные типы данных усложнит написание чистых функций. Мы должны уделять большое внимание. В отдельных случаях мы можем только согласиться их.

В этом случае в JS мы могли бы также понимать чистую функцию по-другому, вместо того, чтобы принимать ее как стандарт, который только «удовлетворяет требованиям» и «не соответствует требованиям», а думать о ней как о диапазоне, здесь есть Чистые функции разной степени.

Как понять «один и тот же ввод, всегда один и тот же вывод»

«Навсегда» в понятии чистых функций в начале статьи может вас смутить, и его следует рассматривать в лексическом объеме, то есть не рассматривать случай модификации константы перед следующим выполнением.

Пример 1

var a = 5;
function A(b) {
  return a + b;
}
A(5);

Является ли функция A чистой функцией? Очевидно, что это очень нечисто.Во время выполнения программы переменная a легко модифицируется, что будет приводить к каждому вызовуA(5)Возвращаемое значение .

Пример 2

Небольшая модификация примера 1

const a = 5;
function A(b) {
  return a + b;
}
A(5);

Это чистая функция, определенный вход, определенный выход.

Пример 3

Замените числовые константы из примера 2 объектами

const obj = {id: 5};
function A(_obj) {
  return _obj.id;
}
A(obj);

Функция A в основном чистая функция, почему вы говорите «в основном»? Потому что есть крайние случаи, как показано ниже

var obj = {
  get id() {
    return Math.random();
  }
}

Обратите внимание, что obj является детерминированным перед передачей в функцию A,getterОна будет выполнена, когда значение будет извлечено, но возвращаемый результат неясен, поэтому функция A в настоящее время не является чистой функцией.случайные числа иDateЭто приведет к тому, что функция будет нечистой, поэтому будьте осторожны при ее использовании.

Кроме того, поскольку объекты являются изменяемыми типами данных, мы вводим переменную каждый разobjв функцию A, нет абсолютной уверенности, что она вернет определенное значение. Но для функции А важны только входящие данные, и для этих данных, если это не крайний случай, описанный выше, она возвращает определенное значение.

Пример 4

const obj = {a: 5};
function A(b) {
  return obj.a + b;
}
A(5);

Это явно очень нечисто, как и в примере 1, обратите внимание на отличие от примера 3.

Пример 5

Небольшая модификация примера 4.

const obj = Object.freeze({a: 5});
function A(b) {
  return obj.a + b;
}
A(5);

Это гораздо чище, но следует отметить, что,Object.freeze()Этот метод не может заморозить вложенные объекты, такие как

const obj = Object.freeze({a: {a: 5}});
obj.a.a = 10;
function A(b) {
  return obj.a.a + b;
}
console.log(A(5));	// 15,不纯

Пример 6

function foo(x) {
  return bar(x);
}

function bar(y) {
  return y + 1;
}

foo(1);

все чисто.

Пример 7

function A(a) {
  return function(b) {
    return a + b;
  }
}
var B = A(5);

Являются ли функция A и функция B чистыми функциями? Сначала посмотрите на функцию A, каждый раз, когда вы вводите параметр, вы получите функцию, состоящую из этого параметра, и полученная функция будет фиксированной, поэтому функция A является чистой функцией; затем посмотрите на функцию B, хотя она, кажется, использует внешней своей собственной переменной а, и эта переменная а может часто меняться, ноФункция B должна быть получена после вызова функции A, а после ее получения переменная a не может быть измененаЭто очень чисто.

Даже если a изменяется до возврата функции B, например.

Пример 8

function A(a) {
  a = 0;
  return function(b) {
    return a + b;
  }
}
var B = A(5);

Вывод такой же.

Но если вы напишете

Пример 9

function A(a) {
  return function(b) {
    return a = a + b;
  }
}
var B = A(5);
console.log(B(1)) // 6
console.log(B(1)) // 7

Дополнительную информацию о побочных эффектах см.«Побочные эффекты функционального программирования на JavaScript»

Использованная литература: