In this article, I will review some of the features of the JS language in combination with two common programming paradigms and understand the views in Composing Software.
Programming paradigm
We discussed programming paradigms earlier, but here’s a quick recap:
Each problem solved in our programming corresponds to a concept, each paradigm is a combination of multiple concepts, and each programming language implements one or more ParadigMs.
Common concept combinations
- When there is only a concept called record, it is called descriptive declarative programming, such as XML
- [Record, PROCEDURE] When added,procedure is called first-order functional programming.
- [Record,procedure,cell (state)] When adding data using cell, it is called imperative programming. For example, in C language,cell represents an information transfer mode similar to that between cells. State Indicates the status.
- [record, procedure, cell (state), Closure] When a closure is added, it can be called sequential object-oriented programming or stateful functional programming Programming), such as Java, when added
thread
And then you have the ability to have concurrency, but I won’t mention it here. - [Record, Procedure,closure] When OOP is subtracted from state, it becomes functional programming, such as Scheme. Js references many of scheme’s features
Object oriented and functional
OOP and FP are two common programming paradigms that are also supported by JS. There are many discussions on this topic, but this is only one of them. More details will be covered in later chapters.
The core
As mentioned above, the difference between the two paradigms is that FP has one less state concept than OOP, namely
Object orientation focuses on the various processing of data, which is the internal state of an object. C+ Primer Plus essentially expresses an object as a data structure for designing and extending itself:
The essence of object-oriented programming (OOP) is designing and extending your own data types
Functional Programming focuses on the flow of data, the external input, and the eventual return of corresponding results. A Brief Intro to Functional Programming is A flow of data, not control flow
The core of Functional Programming is thinking about data-flow rather than control-flow
Applicable scenario
Functional programming vs Object Oriented Programming [Closed]
- Object oriented is used to add new things when there are fixed operations on things. This can be done by adding new classes to implement existing methods. The problem is that many classes need to be edited when new operations need to be added. An example in the project is the encapsulation of the downloader, each of which has fixed actions such as start, pause, and resume.
- When the object itself is fixed, functional programming is used to add operations to the existing object. The current data type can be processed by adding functions. The problem is that when new objects need to be added, many of the functions involved in the processing need to be edited. The most straightforward example is a compiler, which inputs source code and, through a series of operations, outputs object code. Another example is the Loader in WebPack.
Object-oriented expert Michael Feathers also said this:
OO makes code understandable by encapsulating moving parts. FP makes code understandable by minimizing moving parts.
Object-oriented readability is done by encapsulating parts, functional readability is done by minimizing parts, i.e. the former encapsulates the data and the actions of the data, while the latter breaks down operations to minimize them.
How to choose in daily development
Every application is composed of components that are not fixed in form (functions,data structures,classes, etc.). Different programming languages tend to use different atomic elements to form components, such as Java objects, Haskell functions, and so on. And in JS, because of natural support for object-oriented and functional, so often mixed use in the project, we can use object composition to generate data types for functional programming, use functional programming to generate objects for object-oriented programming, no matter how to write, the nature of software development is composition.
The essence of software development is composition
Our job is to use a variety of programming paradigms for each situation, to build a house of components together, and let’s learn more about JS itself before we get into the two paradigms in detail,
Related features in js
We need to have an understanding of the various features of JS in order to use the paradigm tool to better combine the software we develop. This section will mainly refer to ecma262.
Js language design
Brendan Eich developed JS. In this article, he mentioned some problems in the JS design process. Netscape needed to build a scripting language into the browser. According to the leadership, first of all, it needed to Look like Java (so a lot of syntax is similar to Java), while the author preferred Scheme. Therefore, the first-class functions like Scheme and the prototype like Self are selected as the main components in the new language. Thanks to Java, there is a distinction between primitive types and objects, such as String and string.
The above design plus later development became the current JS.
Js Features overview
There are two types of data structures in JS: primitive types and objects. Js objects are not class-based, but can be created in many ways, such as literals or constructors, each of which has a Prototype property for prototype-based inheritance. A constructor’s prototype also has a constructor reference to the constructor itself. This property may change when the implementation inherits, but is not required by convention (see constructor here).
A constructor is a special kind of function that contains an internal method [[Call]], so you can execute code through a function Call. A constructor is a special kind of function. Construct contains internal method [[Construct]], which can be used to create objects through new or super calls.
Objects in JS
Prototype chain
Every object created by a constructor has an implicit reference to the constructor’s Prototype property (which can be accessed with __proto__ but is not recommended), and the prototype itself may have a non-null reference to its Prototype, and so on. This is called a prototype chain. When accessing an attribute of an object, it will first search for the object itself. If it cannot find the object, it will search along the prototype chain until it finds or finds the end and finds no, the attribute on the prototype chain can be overwritten.
In contrast to a language based on class inheritance, generally speaking, the state is owned by the instance, the method is owned by the class, and only the structure and behavior are inherited, whereas js is inheritable. The behavior here is methodically determined; without methods, a class would only have structures.
The end of the prototype chain is null. To determine what the prototype chain of an object actually includes, it can be roughly divided into the following
- If it is a
new Object()
Or literal{}
And its prototype chain is
Var obj={} // obj=>Object. Prototype =>nullCopy the code
- If new calls other constructors, either custom or built-in (such as Array), the built-in constructor does not need to be called by new, as can be done with a literal or without new, as can be done without new
[]
orDate()
), Array is used as an example
Var P=function(){} var P= new P() {} var P= new P(); //p=>P.prototype=>Object.prototype=>nullCopy the code
- If you extend the prototype chain in the previous case, how do you implement inheritance
Create () var q= object.create (p) // q=>p //2. Prototype function Q(){} q.prototype =p var Q =new Q() // Q =>p //3. Object. SetPrototypeOf (obj, prototype) sets the __proto__ attribute to directly modify the prototype chain. This operation is a waste of performance. Function P(){this.b=1} function Q(){this.a=2} var Q =new Q() object.setProtoTypeof (Q, p.prototype) // q=>P.prototype //4. When using call and apply to borrow constructors, Var P=function(v){this.a=v} function Q(v){p.call (this,v)} var Q =new Q(2) // q=>Q.prototype=>Object.prototype=>nullCopy the code
We can use object instanceof constructor to determine if a constructor’s prototype is in the specified object’s prototype chain
function Q(){
this.a=2
}
var q=new Q()
console.log(q instanceof Q)
console.log(q instanceof Object)
Copy the code
GetPrototypeOf (Object) gets the __proto__ attribute of an Object
Object
Object. Prototype has properties and methods that are inherited by all other objects, and some fields may be overridden during specific Object inheritance. In addition, there are many static methods for handling various operations on objects. For details, see MDN
Functions in JS
In JS, all functions are instances of Function, including Object and Function itself, and various built-in constructors (such as Array), so there are
Function.__proto__=== Object. Prototype //true, i.e. Function instanceof Function. __proto__===Function. Prototype //true, Prototype ===Function. Prototype //true Function a(){} a.__proto__===Function.prototype//trueCopy the code
Prototype = Function. Prototype = Function. Prototype = Function.
Function
Funciton. Prototype has some methods that deserve our attention
- func.apply(thisArg, [argsArray])
- function.call(thisArg, arg1, arg2, …)
- function.bind(thisArg[, arg1[, arg2[, …]]])
The first two apply methods of another object to the context of one object, the third modifies the context, and the remaining parameters are used in the returned function call
Js functional programming
In Composing Software, I want to understand a few concepts before getting into functional programming in detail.
concept
Pure Function
A pure function is a function that has the following properties
- The same input always returns the same output
- No side effects
Pure functions are important in functional programming, but in real development, functions have more or less side effects, such as data retrieval and dom manipulation.
Function Composition
Function composition is the combination of two or more functions in order to generate a function or perform an operation.
Shared State
Shared data can be variables, objects, or memory Spaces. One problem with using shared data is that in order to understand the side effects of a function, you need to know the operation history of each shared data. For example, changes to a user’s information on different terminals may conflict, so one-way flow is used in Flux. Another problem is that the order in which operations are performed on shared data can produce different results, such as four operations.
Immutability
An immutable Object cannot be changed after it is created, but JS only provides the immutability of primitive types at the language level, and does not provide this feature for objects. Even methods such as object.freeze () can only freeze Object changes at a certain level. To use immutable data, you can use third-party libraries such as Immer. Immutable objects are the core concept of functional programming. Without immutable objects, the data flow in the program would be uncontrollable. New data should be generated from the original data rather than the original data should be modified.
In practice, at least one immutability and difference must be satisfied for a particular data.
Side Effects
Side effects are operations other than output, such as printing a log or modifying the DOM, and side effects should be avoided in functional programming by keeping them separate from data flow processing.
Reusability Through Higher Order Functions
A higher-order function is any function that takes a function as an argument or returns a function, often used
- Use callback functions, promises, or Monads to abstract or isolate actions, side effects, or asynchronous data flows.
- Create utility functions for manipulating various types of variables
- To create partial functions or currization for reuse or combination of functions
- Returns a combination of functions by concatenating a series of input functions
Containers, Functors, Lists, and Streams
This includes the monads mentioned above, Functors, Applicatives, And Monads In Pictures
A functor data structure can be used to map data, such as [1,2,3]. Map (x => x *2). In other words, it is a container that applies a function to the internal data. Other data structures should work as well; a sequential list can be treated as a stream.
Declarative vs Imperative
Functional programming is a declarative paradigm that abstracts the flow control process rather than describing how to do it in lines of code, as opposed to imperative. For example, the function doubleMap is written imperative
const doubleMap = numbers => { const doubled = []; for (let i = 0; i < numbers.length; i++) { doubled.push(numbers[i] * 2); } return doubled; }; console.log(doubleMap([2, 3, 4])); / / [4, 6, 8]Copy the code
Declarative writing
const doubleMap = numbers => numbers.map(n => n * 2); console.log(doubleMap([2, 3, 4])); / / [4, 6, 8]Copy the code
conclusion
A functional program should have the following characteristics
- Pure functions, not shared data and side effects
- Immutable, not mutable data
- Function composition instead of imperative flow control
- Generic tools rather than specific methods for some data
- Declarative, not imperative
- Expressions, not statements
For FUNCTIONAL applications in JS, please refer TO A GENTLE INTRODUCTION TO FUNCTIONAL JAVASCRIPT series. The ultimate purpose is TO slice the entire logic in the application into different functions, and then combine the functions TO complete the final task. Note the various features of functional programming in the specific processing process.
Common combinations of functions include
- Compose, also known as pipe
const compose = (... functions) => flowIn => functions.reduceRight( ( acc,f ) => f(acc), flowIn )Copy the code
- Curry, I’m going to do a specific Currization here
const add = a => b => a + b;
add(1)(2)
Copy the code
Js object-oriented programming
Js prototype based inheritance is not suitable for implementation of object-oriented encapsulation, inheritance and polymorphism, and es6 implementation class grammar in language level, can easily use other languages and practice to design pattern and design principles of the ts, here recommended specific reference ts implementation of 23 kinds of design patterns and design principles
Whatever the paradigm, it all comes down to assembling the modules into our software.
End and spend