The front-end 60s understand the programming paradigm in one minute

The front-end 60s understand the programming paradigm in one minute

0, 60s In Short

Too long to read the article-a brief summary of 60s

  • Programming paradigm is a programming style that can be divided into imperative, functional (declarative), object-oriented and other paradigms.
  • JS is a dynamic language that supports multiple paradigms. Which paradigm to choose depends on business needs and personal style.
  • There is no absolute difference between good and bad programming paradigm, only suitable and inappropriate.
  • To put it simply, the characteristics of these paradigms.
    • Imperative is more in line with natural logic and easy to understand.
    • The functional style reduces temporary variables and is easy to maintain.
    • Object-oriented is more convenient to expand, and the code reuse degree is high.

1. What is the programming paradigm

Programming paradigm is a type of typical programming style, which refers to a type of typical style of software engineering (contrast methodology).

Such as: imperative programming, functional programming, object-oriented programming and other different programming paradigms.

The embodiment of functional programming in the front-end field

Recently, functional programming has gradually become popular again. Let's take a look at the shadow of functional programming in the front-end field

  • ES6 arrow functions, map, reduce, filter
  • Hook for React 16.8
  • Composition API of Vue3.0

2. Imperative programming

Imperative programming is to pay attention to the calculation execution steps, how to execute, and to pay attention to the process.

Most imperative programming languages support four basic statements

  1. Operation statement
  2. Loop statement (for, while);
  3. Conditional branch statement (if else, switch);
  4. Unconditional branch statements (return, break, continue).

for example

Common table header grouping requirements need to configure the width of each list separately, and the table data is dynamically obtained, so a certain number of repeated fixed-width arrays must be generated according to the data returned by the interface to configure the table width.

  • Use imperative writing
const WIDTHS = [ '10px' , '20px' , '30px' ], LENGTH = 3 ; let arr = []; for ( let i = 0 ; i <LENGTH; i++) { arr = arr.concat(WIDTHS); } //["10px", "20px", "30px", "10px", "20px", "30px", "10px", "20px", "30px"] Copy code
  • Use functional notation
const WIDTHS = [ '10px' , '20px' , '30px' ], LENGTH = 3 ; const arr = Array (LENGTH).fill( '' ).reduce( acc => acc.concat(WIDTHS), []) ; //["10px", "20px", "30px", "10px", "20px", "30px", "10px", "20px", "30px"] Copy code

Pros and cons of imperative programming

  • advantage
    • High performance because of engine optimization
    • Easy to understand, because it conforms to natural programming ideas
  • Disadvantage
    • Generate a large number of temporary variables
    • Code readability is low, you need to read through the code to know what has been done

3. Functional programming (FP)

Functional programming mainly emphasizes how to solve problems through the combination and change of functions and pay attention to the results.

Features of functional programming

  • Functions are "first class citizens"
    • Functions can be operated like other data types, such as assigning values to other variables, as input parameters of the function, and as the return value of the function.
  • Lazy calculation
    • It is executed only when needed, and no meaningless intermediate variables are generated.
  • no side effects"
    • Side effects refer to changes in the state of the system during the process of function calculations, or the interaction between the inside and outside of the function, which produces other effects.
    • Common side effects: changing global variables, sending http requests, dom queries.
  • Referential transparency
    • That is, if the same input is provided, the function always returns the same result.
    • It is completely independent of external state changes (stateless), such as global variables, this pointer, IO operations, etc.
    • PS: No side effects + statelessness can also be called a pure function.

  • Currying
    • Understand as a "processing station", a function that accepts multiple parameters is transformed into a function that accepts a single parameter (the first parameter of the original function), and returns a new function that accepts the remaining parameters and returns the result.
    • Convert a multivariate function into a unit function, which can be called in turn
      f(x,y,z) f(x)(y)(z)
      .
    • For example: find the sum of the squares of two numbers
//Original version const squares = function ( x, y ) { return x * x + y * y; } // Curryed version const currySquares = function ( x ) { return function ( y ) { return x * x + y * y; } } Console .log (Squares ( . 1 , 2 )); Console .log (currySquares ( . 1 ) ( 2 )); duplicated code
  • Function combination (Compose)
    • It is understood as a "pipeline", combining multiple functions into a new function, the initial data is processed sequentially through multiple functions, and finally the overall output.
    • Split the complex logic into simple tasks, and finally combine them to complete the tasks, making the data flow of the entire process more clear and controllable.
    • In order to ensure that the output of each processing station just flows into the input of the next station, it must be a unit function. If the processing station is a multivariate function, you need to use currying to convert it into a unit function, and then put it on the assembly line for combined use.
    • Examples of two function combinations: Pay attention to compose (composition order from right to left)
const compose = ( f, g ) => x => f(g(x)) const f = x => x + 1 ; const g = x => x * 2 ; const fg = compose(f, g); FG ( . 1 ) //. 3 duplicated code
  • Examples of multiple function combinations: If you need a data stream similar to a pipe (from left to right), replace reduce with reduceRight.
const compose = ( ...fns ) => { return fns.reduce( ( acc,cur ) => { return ( ...args ) => { return acc(cur(...args)) } }) } //The last returned function is executed first const f = x => { console .log( 'f: ' , x); return x + 1 ; } const g = x => { console .log( 'g: ' , x); return x + 1 ; } const t = x => { console .log( 't: ' , x); return x + 1 ; } compose(f, g, t)( 1 ); T//:. 1 //G: 2 //F:. 3 copy the code

Pros and cons of functional programming

  • advantage
    • Simple code, fast development
      • Function reuse rate is very high, reducing repetition, and fast development speed
    • Easy to maintain
      • Reduce the declaration and maintenance of state variables
    • Less chance of error
      • Emphasize pure functions, no side effects
  • Disadvantage
    • Poor performance, easy to over-abstract packaging
      • For example, to use imperative style, you only need variables + imperative style (one-level loop), use functional style, and don't use external variables (double loop).
      • In a non-functional language such as JS, the functional method is slower than directly writing statement instructions (the engine will be specially optimized for many instructions). For example, pure loops are several times faster than native map performance.
    • Memory is easy to occupy too high
      • In order to realize the immutability of the object state, create more new objects. Consuming more memory space, the JS engine is under pressure for garbage collection.

4. Object-Oriented Programming (OOP)

3.characteristics of object-oriented

Encapsulation

  • Encapsulation means to hide the properties and implementation details of the object, and only expose the API interface to the outside.
  • Combine the abstracted data and behavior (or function) to form an organic whole.
class Person { constructor ( name ) { this .name = name; } work () { console .log( ` ${ this .name} is working hard` ); } static touch () { console .log( "Touch the fish" ); } } let boy = new Person( "Joe" ); boy.touch (); //Not boy.touch IS A function boy.work (); //Working Hard Joe IS Person.touch (); //The FISH Touch duplicated code

inherit

  • Inheritance means that the subclass can inherit the parent class, so that the subclass object (instance) has the properties and methods common to the parent class, without the need to write repeated code.
  • After the subclass inherits the parent class, the subclass will have the properties and methods of the parent class, and the subclass can also declare its own properties and methods.
class Person { constructor ( name ) { this .name = name; } work () { console .log( ` ${ this .name} is working hard` ); } static touch () { console .log( "Touch the fish" ); } } class FatMan extends Person { constructor ( name ) { super (name); } drink () { console .log( "Hey! It's three o'clock, drink tea first!" ); } } let uncle = new FatMan( "Brother Drinking Tea" ); uncle.work(); //Brother Drinking Tea is working hard uncle.drink(); //Hey! It's three o'clock, tea first! uncle.touch (); //Not uncle.touch IS A function to copy the code

Polymorphism

  • Polymorphism literally means "multiple states", allowing pointers of subtypes to be assigned to pointers of supertypes. That is, the same operation acts on different objects, can have different interpretations, and produce different execution results.
  • The manifestations of polymorphism include rewriting, overloading and interfaces. The only polymorphism that native JS can achieve is rewriting.
  • Rewriting: Rewriting is that the subclass can inherit the method in the parent class without rewriting the same method. But sometimes the subclass does not want to directly inherit the methods of the parent class. If you want to make adjustments and changes, you must override the methods of the parent class. We can also call it method coverage.
class Person { constructor ( name ) { this .name = name; } getName () { console .log( this .name); } work () { console .log( ` ${ this .name} is working hard` ); } static touch () { console .log( "Touch the fish" ); } } class FatMan extends Person { constructor ( name ) { super (name); } work () { console .log( "Do it* do it!" ); } drink () { console .log( "Hey! It's three o'clock, drink tea first!" ); } } const boy = new Person( 'Joe' ); const uncle = new FatMan( ' Yincha Ge' ); boy.getName(); //Joe boy.work(); //Joe is working hard uncle.getName(); //Brother Yincha uncle.work(); //Do Lu*, do it! Copy code

5. How to choose

  • The meaning of learning programming paradigm is to enrich your programming ideas, to choose the most suitable programming weapon in the face of a specific scenario, and to use it flexibly.
  • Imperative, functional, and object-oriented are not inherently superior or inferior. We can choose the appropriate programming paradigm according to the needs in actual development.

Reference article

recommend

  • Functional programming library ( ramda.cn/ )