Before we get into the topic, we need to be clear about the concept that things like functional programming and object-oriented programming are just tools or specifications, and their purpose is to develop our programming mind. We know that the essence of programming is actually to use code to instruct the computer to do something, but when we are faced with a complex problem, in fact, most of our time is not writing code, but coordination, we need to understand and coordinate the relationship between different modules.

Functional programming

1. What is functional programming

Functional programming is a programming paradigm that uses functions to wrap up operations. When we want to implement a complex function, we can calculate the result by combining various functions. Let’s look at an example.

['book-red'.'pen-black'.'leaf-green']
// The result of the conversion[{name:Book,
        color:Red
    },
    {
        name:Pen,
        color:Black
    },
    {
        name:Leaf,
        color:Green
    }
]
Copy the code

If you see this problem as you used to see it before, you can go straight to it and do the whole conversion process in one function. Let’s try it out:

const fun = (arr) = > {
  const res = [];
  for (const val of arr) {
    let [name, color] = val.split("-");
    name = name[0].toUpperCase() + name.slice(1);
    color = color[0].toUpperCase() + color.slice(1);
    res.push({ name, color });
  }
  return res;
};

const res = fun(["book-red"."pen-black"."leaf-green"])
Copy the code

This programming method is also called imperative programming, but this writing method also has its disadvantages, such as poor readability, too many intermediate variables, especially when there is a problem, it is difficult to check the problem, this author in the process of brushing experience.

So what if we were to use functional programming? Functional programming requires us to figure out the problem before we write it. Here we go step by step:

  • First we need a function to help us convert strings into objects.
const trasnformStringToObj = curry((keys,info) = > {
  const obj = {};
  keys.forEach((key,index) = > {
    obj[key] = info[index]
  });
  return obj
})
Copy the code
  • Info contains converted information, such as [Book, Red], so we need a function that capitalizes the beginning of the string.
const upperCase = s= > s[0].toUpperCase() + s.slice(1);
Copy the code
  • Before converting, we need to split and combine strings. We can hack map and split implementations of these functions.

Now that we have these functions, we can eventually combine them together, using the compose function:

const upperCaseInfo = compose(trasnformStringToObj(['name'.'color']),map(upperCase), split(The '-'))

const getRes = map(upperCaseInfo);
const res = getRes(['book-red'. ] )Copy the code

From here we can obviously see the implementation process of functional programming, his focus is on the function rather than the process, when we have more functions can be divided into functions, which is also conducive to the reuse of the code.

2. Features of functional programming

  • The function is a first-class citizen

In JavaScript, functions are considered first-class citizens, that is, functions have equal status with other data types. They can be assigned to other variables as variables, passed as parameters, returned as values from other functions, etc. It is because of their special status that functional programming can be implemented.

  • Declarative programming

As I said above, with functional programming to solve the problem, we’ll be the first to want to understand the question to write again, here would like to understand is that need us to declare in advance what we need to do, not what to do, this way of programming is to become a declarative programming, under this paradigm, we don’t need to care about the function of the specific implementation, The advantage of this is that the code is more readable and we don’t need to worry about the specific logic and optimization of the function as long as we are concerned with our own business logic.

  • Pure functions

Pure function has three characteristics, one is no side effects, two is transparent reference, three is immutable data, the following one.

No side effects:

No side effects means that the function itself does not depend on and does not modify external data. The most common external variable is this. Side effects not only reduce the overall readability of the program, but also sometimes cause unexpected and difficult to detect errors, as shown in the following example:

var count  = 1;
const fun = () = > {
    count += Math.random();
    return count + this.total;
}
Copy the code

There are two problems with the above code. One is that it uses the total attribute on the external this. We can’t predict when this attribute will be changed, and the other is that it changes the external attribute count, which may affect other places where count is used.

Reference transparent

Reference transparency means that the input of the same parameter always returns the same output. In simple terms, the return value of a function is only affected by the input, as in the following example:

const add = (a,b) = > a + b;
Copy the code

Immutable data

Immutable data mainly refers to the input parameter of the data type. If you must change it, the best way is to generate a new copy of the data. Immer.js is recommended here.

Function programming in React

  • Pure functions

How do pure functions manifest themselves in React? Let’s start with an example:

const APP = ({ count }) = > {
  return <p>{`Count: ${count}`}</p>;
};
Copy the code

Is just a simple function component, he accepts a parameter and return a P tag, it is very accord with our reference transparent this principle, will have the same output given the same input, in the React it follows the one-way flow of data, that is to say, when my data from the parent component flow to the child components, data will be immutable, That is, the child component cannot change the incoming data, which is a good example of pure functions.

  • Declarative programming

In React, we only need to declare our UI, and React helps us complete the corresponding data update, DOM tree comparison construction and rendering.

  • composition

In functional programming, composition is the act of building complex functions by combining or linking multiple smaller functions. In React, we can also build complex components by using its children property, which gives us the flexibility to decide what’s inside a component and customize it to get the desired output. To learn more about this property, see this article.

4, summarize

The pros and cons of functional programming are summarized below:

  • The code is concise and easy to understand

First of all, functional programming uses declarative code, so it is particularly easy to understand, and functional programming can effectively improve the reuse rate of functions by differentiating functions.

  • Fast concurrency

Using immutable data management avoids locking in many cases and enables faster concurrent processing.

  • Error rate is less

We split each function into specific functions, and each function is guaranteed to be pure, which reduces the probability of error and improves the efficiency of troubleshooting problems.

Functional programming is not perfect, and because it has so many advantages, it is inherently flawed in the following ways:

  • High performance consumption

Functional programming as opposed to imperative programming is one of the biggest performance, then we the example above, we put the string operations are placed in a function, so that I would only need one execution context, for the functional programming, due to excessive we split function, leading to constant in different contexts to switch, That’s a lot of overhead in terms of performance.

  • High resource occupancy

In functional programming we expect data to be immutable, which means that every time we update data we need to create a new one to override the previous one, especially if we want to travel in real time.

Object-oriented programming

1. What is object-oriented programming

Object orientation is also a development model that organizes code around data or objects rather than functionality and logic. It shifts the focus of developers from logic to the data they want to manipulate. It wraps data and methods in a single class, which facilitates code reuse and extensibility.

2. Characteristics of object-oriented programming

  • encapsulation

Means that all of the data packages and the methods are encapsulated within the object, by the developers themselves selectively to public which attributes and methods, for creating an instance of the he can access only the public attributes and methods, and for other objects is the right to access such or make changes, wrap this feature provides higher security for the program.

  • inheritance

Inheritance means that code can be reused, and the concept of subclasses and superclasses is a good example. Subclasses have all the attributes and methods of their parent class, avoiding double definition of data and methods, while maintaining a unique tomographic structure.

  • polymorphism

Polymorphism means that an object is designed to share behavior, that an inherited subclass can override behavior shared by its parent class with a new method, and that polymorphism allows the same method to perform two different behaviors: override and overload.

Override We just said that subclasses can use their own methods to override the parent class, as in this example:

class Person {
    play(){
        console.log('Person')}}class Student extends Person {
    play(){
        console.log('Student')}}const student = new Student()
student.play() //student
Copy the code

Overloading means that methods can have the same name, but different types or numbers of arguments are passed to the method, and the corresponding function is executed based on the arguments.

3, summarize

advantages

  • High efficiency development

In software development, the real world is abstracted according to the needs of the design, producing classes. This approach to problem solving, close to everyday life and natural way of thinking, is bound to improve the efficiency and quality of software development.

  • Easy maintenance, clear structure

The structure designed with object-oriented thought is highly readable. Because of the existence of inheritance, even if the requirements are changed, the maintenance is only in the local module, so the maintenance is very convenient and low cost.

  • Easy extension

Due to the characteristics of inheritance, encapsulation and polymorphism, the system structure with high cohesion and low coupling is naturally designed, which makes the system more flexible, easier to expand, and lower cost.

  • reusable

Code can be reused through inheritance, which means we don’t have to write the same code for multiple people

disadvantages

  • Excessive objectification

We know that if a subclass inherits from a parent class it can have data and methods defined in that parent class, and that parent class has to be a class, but sometimes I just want to reuse a piece of code, because of inheritance I have to define a parent class and object it, like if WE want to make a tabel list, Because tabel components in different scenarios require different methods and data, but they also have many of the same data and methods, such as PageNo, PageSize, selectedRowKeys, etc., which are completely reusable, we have to cram these data into a class.

  • Sharing of state

In the object oriented state share is often happen, because we defined in object-oriented data is variable, and that is to say, I define an instance, the state of the instance can be in different places according to the way they think is the most suitable to be modified, which in turn as the code is more and more complicated to program reasoning also becomes more and more complex.

  • Concurrency issues

The promiscuous sharing of mutable state in object orientation makes this code nearly impossible to parallelize. Complex mechanisms have been invented to solve this problem. Thread locking, mutexes, and many other mechanisms have been invented. Of course, this complex approach has its drawbacks — deadlocks, lack of composability, and the difficulty and time consuming of debugging multithreaded code. Not to mention the added complexity of using this concurrency mechanism.

  • Memory consumption and low performance

This problem is also inherent in object orientation, because the methods and data we define are encapsulated in a class, which is large, and a new instance is needed to use the methods and data on this class everywhere.