More on this blog at github.com/zhuanyongxi…

Pure functions are the foundation of functional programming and need to be understood. For pure functions, see “Why JavaScript Functional Programming is Functional (Non-technical Bullshit).”

The concept of pure functions:

A pure function is one in which the same input always returns the same output without any observable side effects.

His point is that “the same input will always get the same output”, and the side effects mentioned later are also to satisfy this point.

Before I get into the details of pure functions, I’ll talk about two other concepts: mutable and immutable data types.

We know that in JavaScript, primitive data types are immutable; they can only be replaced, not modified. For example, when we operate on a string, we cannot change the string itself.

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

All we can do is reassign the returned string to the variable.

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

Reference data types are mutable, and only an address exists in a variable. For mutable features, Facebook’s immutable. Js is specifically enhanced, along with more radical approaches like Clojurescript.

Why are we talking about these two concepts?

Not to mention the possible side effects in the system environment where JS is running, just looking at these variable data types will increase the difficulty of writing pure functions. Be aware that in some cases we can only choose to accept.

In this way, in JS, we might as well put the pure function in another way to understand, do not take it as a only “fully meet the requirements” and “do not meet the requirements” standard, and to imagine it as a range, here there are high and low degrees of pure function.

How to understand “The same input, always get the same output”

The “always” in the concept of pure functions at the beginning of this article may confuse you, but it should be considered in lexical scope, that is, not in the case of modifying constants before the next execution.

Patients with a

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

Is function A A pure function? Obviously very impeccably, variable A can be easily modified during program execution, which causes the return value of each call to A(5) to change.

Example 2

Example 1 is modified slightly

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

This is a pure function, a certain input, a certain output.

Example 3

Replace example 2 numeric constants with objects

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

Function A is basically A pure function. Why is it basically? Because there are extremes like this

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

Note that obj is determined before it is passed to function A, and the getter is executed when the value is evaluated, but the result returned is undefined, so function A is not pure at this point. Random numbers and dates both cause function impure, so be careful when using them.

In addition, since objects are mutable data types, we are not absolutely confident that we will return A definite value every time we enter the variable obj into function A. But for function A, it only cares about what data is passed in, and for that data, as long as it is not the extreme case above, it returns A certain value.

Cases of four

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

This is obviously impure, same as example 1, notice the difference with example 3.

Cases of five

Example 4 is modified slightly

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

This is much purer, but note that the object.freeze () method does not freeze nested objects, for example

const obj = Object.freeze({a: {a: 5}});
obj.a.a = 10;
function A(b) {
  return obj.a.a + b;
}
console.log(A(5));	// 15 is not pure
Copy the code

Cases of six

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

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

foo(1);
Copy the code

Are pure.

Cases of seven

function A(a) {
  return function(b) {
    returna + b; }}var B = A(5);
Copy the code

Are functions A and B pure functions? So function A, every time you put in an argument, you get A function that takes that argument, and the resulting function is fixed, so function A is pure; Even though function B looks as if it uses an external variable, a, which may change frequently, function B cannot get it until it calls function A, and once it gets it, variable A cannot change, so it is pure.

Even if a is modified before returning function B, for example

Cases of eight

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

The conclusion is the same.

But if I write it this way

Cases of nine

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

For more on side effects, see Side Effects of JavaScript Functional Programming.

References:

  • JS functional programming guide
  • Functional-Light JavaScript