Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Example Analysis of JavaScript functional programming

2025-02-27 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

This article shares with you the content of a sample analysis of JavaScript functional programming. The editor thinks it is very practical, so share it with you as a reference and follow the editor to have a look.

I have seen many explanations about functional programming, but most of them stay at the theoretical level, and some are only for pure functional programming languages such as Haskell. The purpose of this article is to talk about the concrete practice of functional programming in JavaScript in my eyes. The reason why it is "in my eyes", that is, what I say only represents a personal point of view, may conflict with some strict concepts.

This article will omit a lot of formal concept introductions, focusing on what is functional code in JavaScript, what is the difference between functional code and general writing, what benefits functional code can bring to us, and what some common functional models have.

Functional programming that I understand

I think functional programming can be understood as using functions as the main carrier of programming, using functions to disassemble and abstract general expressions.

What are the advantages of this compared to imperative? The main points are as follows:

The semantics are clearer.

Higher reusability

Better maintainability

Limited scope and few side effects

Basic functional programming

The following example is a concrete functional representation

Javascript code

/ / each word in the array, capitalized / / generally written const arr = ['apple',' pen', 'apple-pen']; for (const i in arr) {const c = arr [I] [0]; arr [I] = c.toUpperCase () + arr [I] .slice (1);} console.log (arr) / / functional writing-function upperFirst (word) {return word [0] .toUpperCase () + word.slice (1);} function wordToUpperCase (arr) {return arr.map (upperFirst);} console.log (wordToUpperCase (['apple',' pen', 'apple-pen'])) / / functional console.log (arr.map ([apple', 'pen',' apple-pen'], word = > word [0] .toUpperCase () + word.slice (1)

When the situation becomes more complicated, there are several problems with the way the expression is written:

The meaning is not obvious, and gradually becomes difficult to maintain.

Poor reusability will result in more code

It produces a lot of intermediate variables.

Functional programming solves the above problems very well. First of all, see the functional writing method 1, which uses the function encapsulation to disassemble the function (the granularity is not unique), and encapsulates it into different functions, and then uses the combined calls to achieve the purpose. This makes it clear and easy to maintain, reuse, and extend. Secondly, using higher-order function, Array.map instead of for. Of does array traversal, reducing intermediate variables and operations.

The main difference between functional writing method 1 and functional method 2 is that we can consider whether there is the possibility of subsequent reuse of the function, if not, the latter is better.

Chain optimization

From the above functional writing method 2, we can see that in the process of writing functional code, it is easy to cause horizontal extension, that is, multi-layer nesting. Let's give an example of a more extreme point.

Javascript code

/ calculate the sum of numbers / / General console.log (1 + 2 + 3-4) / / functional function sum (a, b) {return a + b;} function sub (a, b) {return a-b;} console.log (sum (sum (1,2), 3), 4) This example is only to show the more extreme cases of horizontal extension, as the number of nesting layers of the function continues to increase, resulting in a significant decline in the readability of the code, but also prone to errors. In this case, we can consider a variety of optimization methods, such as the following chain optimization. / / optimized writing (well, you read it correctly, this is how lodash is chained) Javascript code const utils = {chain (a) {this._temp = a; return this;}, sum (b) {this._temp + = b; return this;}, sub (b) {this._temp-= b; return this }, value () {const _ temp = this._temp; this._temp = undefined; return _ temp;}}; console.log (utils.chain (1) .sum (2) .sum (3) .sub (4) .value ())

After rewriting in this way, the structure as a whole will become clearer, and what each link of the chain is doing can be easily shown. Another good example of the comparison between function nesting and chaining is the callback function and the Promise pattern.

Javascript code

/ / request two interfaces sequentially / / callback function import $from 'jquery'; $.post (' an if rs2 to target targets, (rs) = > {if (URL) {$.post) ('a rs2 rs2 to an other target, (post) = > {post (rs2) {$.post);});}) / / Promise import request from 'catta'; / / catta is a lightweight request tool that supports fetch,jsonp,ajax and has no dependencies on request (rs = > rs? $.post): Promise.reject (). Then (rs2 = > rs2? $.post): Promise.reject ()

As the nesting level and single-layer complexity of the callback function increases, it will become bloated and difficult to maintain, while the chained structure of Promise can still scale vertically at high complexity, and the hierarchical isolation is clear.

Common functional programming models

Closure (Closure)

A block of code that can keep local variables from being released is called a closure

The concept of closure is abstract. I believe everyone knows and uses this feature more or less.

So what benefits can closures bring to us?

Let's take a look at how to create a closure:

Javascript code

/ / create a closure function makeCounter () {let k = 0; return function () {return + + k;};} const counter = makeCounter (); console.log (counter ()); / / 1 console.log (counter ()); / / 2

The code block of the makeCounter function refers to the local variable k in the returned function, so that the local variable can not be recovered by the system at the end of the function execution, resulting in a closure. The purpose of this closure is to "retain" the local variable so that the variable can be reused when the inner function is called, unlike a global variable, which can only be referenced within the function.

In other words, closures actually create "persistence variables" that are private to the function.

So from this example, we can conclude that the conditions for closures are:

There are inner and outer functions.

The inner layer function refers to the local variable of the outer layer function.

The purpose of closures

The main purpose of closures is to define scoped persistent variables that can be used as intermediate amounts for caching or computation, and so on.

Javascript code

/ / simple caching tool / / Anonymous function creates a closure const cache = (function () {const store = {}; return {get (key) {return store [key];}, set (key, val) {store [key] = val;}} ()); cache.set ('asides, 1); cache.get (' a') / / 1

The above example is an implementation of a simple caching tool where anonymous functions create a closure so that store objects can always be referenced and not recycled.

The disadvantages of closures

Persistent variables will not be released normally, continue to take up memory space, it is easy to cause memory waste, so it generally requires some additional manual cleaning mechanism.

Higher order function

A function that accepts or returns a function is called a higher order function.

It sounds like a cold word, but in fact we often use it, but we just don't know their names. The JavaScript language natively supports higher-order functions because the JavaScript function is a first-class citizen and can be used both as an argument and as a return value of another function.

We can often see many native higher-order functions in JavaScript, such as Array.map, Array.reduce, Array.filter

Let's take map as an example, and let's see how it works.

Map (Mapping)

Mapping is for a set, that is, every item of the set is transformed the same way to produce a new set.

As a higher-order function, map accepts a function parameter as the logic of the mapping.

Javascript code

/ / add one to each item in the array to form a new array / / the general way of writing is const arr = [1jie 2jue 3]; const rs = []; for (const n of arr) {rs.push (+ + n);} console.log (rs) / / map rewrite const arr = [1jue 2jue 3]; const rs = arr.map (n = > + + n)

It is generally written above, using for. Traversing the array in an of loop creates additional operations and risks changing the original array.

The map function encapsulates the necessary operations, so that we only need to care about the function implementation of the mapping logic, reducing the amount of code and the risk of side effects.

Corey (Currying)

Given some of the parameters of a function, generate a new function that accepts other parameters

You may not hear the term very often, but anyone who has used undescore or lodash has seen him.

There is a magical _. Partial function, which is the implementation of Coriarization.

Javascript code

/ / get the relative path of the target file to the base path / / generally write const BASE ='/ path/to/base'; const relativePath = path.relative (BASE,'/ some/path'); / _ .parical rewrite const BASE ='/ path/to/base'; const relativeFromBase = _ .partial (path.relative, BASE); const relativePath = relativeFromBase ('/ some/path')

Through _. Partial, we get a new function relativeFromBase, which is equivalent to calling path.relative when called, and the first parameter is passed into BASE by default, and the subsequent arguments are sequenced later.

In this case, what we really want to do is to get the path relative to the BASE each time, not to any path. Corialization can make us only care about some of the parameters of the function, which makes the purpose of the function clearer and the call easier.

Combination (Composing)

Combine the capabilities of multiple functions to create a new function

Also, the first time you met him was probably in lodash, the compose method (now called flow).

Javascript code

/ / capitalize each word in the array, do Base64 / / general writing (one of them) const arr = ['pen',' apple', 'applypen']; const rs = []; for (const w of arr) {rs.push (btoa (w.toUpperCase ();} console.log (rs); / _ .flow rewrite const arr = [' pen', 'apple',' applypen'] Const upperAndBase64 = _ .partialRight (_ .map, _ .flow (_ .upperCase, btoa)); console.log (upperAndBase64 (arr))

_. Flow combines the ability to uppercase and Base64 functions to generate a new function. It is convenient to be used as a parameter function or subsequent reuse.

My own point of view

My understanding of JavaScript functional programming may be different from many traditional concepts. I do not only think that high-order function operational functional programming, other things such as ordinary function combined calls, chain structures, etc., I think belong to the category of functional programming, as long as they take functions as the main carrier.

And I don't think functional programming is necessary, nor should it be a mandatory requirement. Like object-oriented or other ideas, it is one of the ways. In more cases, we should be a combination of several, rather than limited to concepts.

Thank you for reading! This is the end of this article on "sample Analysis of JavaScript functional programming". I hope the above content can be of some help to you, so that you can learn more knowledge. if you think the article is good, you can share it for more people to see!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report