当前位置: 首页 > news >正文

福州互联网公司排行榜360优化大师官网

福州互联网公司排行榜,360优化大师官网,珠三角网站建设,重庆网站开发服务介绍: 函数式编程(FP)是一种编程范式,这意味着一种基于一些原则来思考软件构建的方法,比如 纯函数、不可变性、一等与高阶函数、函数组合、闭包、声明式编程、递归、引用透明性、柯里化 和 部分应用。 当这些原则有效…

介绍:

函数式编程(FP)是一种编程范式,这意味着一种基于一些原则来思考软件构建的方法,比如 纯函数、不可变性、一等与高阶函数、函数组合、闭包、声明式编程、递归、引用透明性、柯里化 和 部分应用

当这些原则有效地应用到 JavaScript 中时,可以使得代码更加模块化、可维护、健壮、易于理解、可测试,并且能够优雅地处理复杂的问题。

这篇文章看起来可能有点长,但不会那么理论化。

让我们开始逐一实验吧:

1. 纯函数:

两条规则:

  1. 给定相同的输入,总是返回相同的结果。
  2. 不产生副作用。

用处: 容易重构,使代码更具灵活性和适应性。

例子 1:

// 不纯的函数。
let a = 4;
const multiplyNumbers = (b) => a *= b;multiplyNumbers(3);
console.log(a); // 第一次调用:12
> 12
multiplyNumbers(3);
console.log(a); // 第二次调用:36
> 36// 修改了外部变量,所以不是纯函数。
// 纯函数版本。
const multiplyNumbers = (x,y) => x * y;multiplyNumbers(2, 3);
> 6

例子 2:

// 不纯的函数。
addNumberarr = (arr, num) => {
arr.push(num);
};
const testArr = [1,2,3];
addNumberarr(testArr, 4);console.log(testArr);
> [1, 2, 3, 4]// 修改了输入数组,所以不是纯函数。
// 上面的纯函数版本。
addNumberarr = (arr, num) => {
return [...arr, num];
};
const testArr = [1,2,3];
addNumberarr(testArr, 4);
> [1, 2, 3, 4]

JS 内置的纯函数:

arr.reduce()
arr.map()
arr.filter()
arr.concat()
arr.slice()
arr.each()
arr.every()
... - 扩展语法

JS 内置的非纯函数:

arr.splice()
arr.push()
arr.sort()
Math.random()

2. 不可变性:

一旦创建就不能改变状态的对象。

一个简单的例子就是使用 slice 方法来帮助你轻松理解它的含义。

const arr = [1,2,3,4];const slicedArray = arr.slice(1,2);slicedArray
> [2]arr
> [1, 2, 3, 4]

如果你看上面的例子,slice 并没有改变原始数组 arr。而下面的例子则不同:

const arr = [1,2,3,4];arr.push(5);
> 5arr
> [1, 2, 3, 4, 5]

原始数组 arr 被修改了。这并不是说我们不应该使用 push,但是在大多数情况下我们可以避免这种情况。一个简单的例子是:

const arr = [1,2,3,4];const newArr = [...arr, 5];arr
> [1, 2, 3, 4]newArr
> [1, 2, 3, 4, 5]

上面的所有都是简单例子,可能不会造成任何问题。但是,如果我们在整个文件中尽可能多地修改同一个对象,就会带来许多问题。因为我们需要跟踪这个对象被修改了多少次以及以何种方式被修改。

为了解决这个问题,我们需要避免修改对象。

3. 一等函数

一等函数是指把函数当作一等公民的概念,意味着它们被视为常规变量或值。这让函数可以像字符串或数字等其他数据类型一样被操作和使用。这允许函数作为参数传递给其他函数,从其他函数返回值,以及被赋值给变量。JavaScript 支持这一点。

它打开了强大的编程技术的大门,比如高阶函数、函数组合,以及抽象的创建。

4. 高阶函数:

一个函数可以接受另一个函数作为参数或者返回一个函数作为结果,这样的函数被称为高阶函数。

  1. 返回一个函数的函数
const higherOrderFunc = function() {return function() {return 12;}
}// 返回下面的函数,所以它是高阶函数。
higherOrderFunc(); 
> ƒ () {return 12;}higherOrderFunc()();
> 12
  1. 接受一个函数作为参数的函数
const testFunc = function(x) {return x + 12;
}// 接受函数作为参数。
const higherOrderFunc = function(testFunc) {return testFunc(8);
}higherOrderFunc(testFunc);
> 20

例子 1:

function calculate(operation, numbers) {return operation(numbers);
}function addition(numbers) {let sum = 0;for (const number of numbers) {sum+=number;}return sum;
}function multiply(numbers) {let sum = 1;for (const number of numbers) {sum*=number;}return sum;
}const numbers = [1,2,3,4,5];
console.log(calculate(addition, numbers));
> 15console.log(calculate(multiply, numbers));
> 120// calculate(multiply, numbers) - 传递函数作为参数时不加括号。

高阶函数的好处:

减少代码重复
单一职责

在 JavaScript 中,函数可以接受原始类型或对象作为参数并返回相同类型,称为一阶函数。

JS 内置的高阶函数有:

arr.reduce(), arr.forEach(), arr.filter(), arr.map()

5. 函数组合:

这是一种方法,其中将一个函数的结果传给下一个函数。

const add = (x, y) => x+y;const subtract = (x) => x-4;const multiply = (x) => x * 8;// add 的结果传给 subtract,其结果再传给 multiply。
const result = multiply(subtract(add(2, 3)));result;
> 8

看起来很清晰,但如果我们要一个接一个地调用更多函数会怎么样呢?让我们试试更干净的方法。

const compose = (...functions) => x => functions.reduceRight((total, f) => f(total), x);const add = x => x+2;const subtract = x => x-1;const multiply = x => x * 8;compose(multiply, subtract, add)(2);
> 24

我们也可以使用 reduce 来实现:

const pipe = (...functions) => x => functions.reduce((total, f) => f(total), x);const add = x => x+2;const subtract = x => x-1;const multiply = x => x * 8;pipe(add, subtract, multiply)(2);
> 24

pipe - 从左到右执行。
compose - 从右到左执行。

6. 声明式编程:

声明式: 告诉 做什么

命令式: 告诉 怎么做

例子: 找出部门为 ‘justCode’ 的员工及其工资总和。

命令式风格:

const employees = [
{id: 1, name: 'james', dept: 'admin', salary: 10000},
{id: 1, name: 'Tom', dept: 'finance', salary: 10000},
{id: 1, name: 'peter', dept: 'justCode', salary: 12500},
{id: 1, name: 'tunner', dept: 'justCode', salary: 14500},
];const justCodeDept = [];// 根据部门名称筛选员工。
for (let i=0; i<employees.length; i++) {if (employees[i].dept === 'justCode') {justCodeDept.push(employees[i]);}
}// 计算 justCodeDept 员工的工资总和。
let summation = 0;
for (j = 0; j<justCodeDept.length; j++) {summation = summation + justCodeDept[j].salary;
}console.log(summation);

声明式风格:

const employees = [
{id: 1, name: 'james', dept: 'admin', salary: 10000},
{id: 1, name: 'Tom', dept: 'finance', salary: 10000},
{id: 1, name: 'peter', dept: 'justCode', salary: 12500},
{id: 1, name: 'tunner', dept: 'justCode', salary: 14500},
];console.log(employees.filter(item => item.dept === 'justCode').reduce(((previousValue, currentValue) => previousValue += currentValue.salary), 0));

7. 柯里化:

将接收多个参数的函数拆分成一系列函数,每个函数只接收单个参数。

例子 1:

通常我们写:

function addition(x, y, z) {return x + y + z;
}addition(1, 2, 3);
> 6

柯里化版本:

function addition(x) {return function addY(y) {return function addZ(z) {return x + y + z;}}
}addition(1)(2)(3);
> 6

使用箭头函数:

addition = (x) => (y) => (z) => x + y + z;addition(1)(2)(3);
> 6

例子 2:

function formWelcomNote(name) {name = `Hello ${name}, `;return function(location) {location = `Welcome to ${location},`;return function(section) {return `${name}${location} Please visit ${section} section`}}
}formWelcomNote('Yester')('VK Just Code Articles')('JS Articles');
> 'Hello Yester, Welcome to VK Just Code Articles, Please visit JS Articles section'

我们也可以这样写:

formWelcomNote = (name) => {name = `Hello ${name}, `;return (location) => {location = `Welcome to ${location},`;return (section) => {return `${name}${location} Please visit ${section} section`}}
}formWelcomNote('Yester')('VK Just Code Articles')('JS Articles');
> 'Hello Yester, Welcome to VK Just Code Articles, Please visit JS Articles section'

例子 3:

function calculation(fn) {switch (fn) {case 'add': return (a, b) => a + b;case 'sub': return (a, b) => a - b;case 'mul': return (a, b) => a * b;case 'div': return (a, b) => a / b;}
}
console.log(calculation('mul')(4, 2));

8. 部分应用:

你为一个函数固定一定数量的参数,并生成一个新的带有较少参数的函数。这个新函数可以在稍后的时间用剩下的参数来调用。部分应用有助于创建更加专业和可重用的函数。

例子:

function add(a, b) {return a + b;
}// 部分应用第一个参数
const add2 = add.bind(null, 2);console.log(add2(5));  // 输出:7 (2 + 5)
console.log(add2(8));  // 输出:10 (2 + 8)

9. 引用透明性:

JavaScript 中的一个表达式可以用它的值来替代,这种特性叫做引用透明性。

const add = (x, y) => x + y;const multiply = (x) => x * 4;// add (3, 4) 可以被替换为 7 —— 引用透明性。multiply(add(3, 4)); 
> 28multiply(add(3, 4));
> 28
const arr = [];
const add = (x, y) => {const addition = x + y;arr.push(addition);return addition;
}const multiply = (x) => x * 4;// 在这里,我们不能用 7 替换 add(3, 4),因为它会影响程序逻辑。
multiply(add(3, 4));
> 28multiply(add(3, 4));
> 28

10. 闭包:

闭包让你可以从内部函数访问外部函数的作用域。

function outer() {const name = 'test';function inner() {// 'name' 从外部函数可以访问到内部函数中console.log(name);}inner();
}
outer();> test
function outerAdd(x) {return function(y) {return x + y;};
}const outer12 = outerAdd(12); // x 为 12.
const outer14 = outerAdd(14); // x 为 14.const outer12Result = outer12(12); // y 为 12.
console.log(outer12Result);
> 24const outer14Result = outer14(14); // y 为 14.
console.log(outer14Result);
> 28

或者,你也可以像下面这样使用箭头函数:

outerAdd = x => y => x + y;const outer12 = outerAdd(12);
const outer14 = outerAdd(14);const outer12Result = outer12(12);
console.log(outer12Result);
> 24const outer14Result = outer14(14);
console.log(outer14Result);
> 28

使用闭包的计数器示例:

function outer() {let counter = 0;return function inner() {counter += 1;return counter;}
}
const out = outer();console.log(out());
console.log(out());
console.log(out());> 1
> 2
> 3

11. 递归:

递归是一种编程技巧,在其中函数通过自我调用来解决问题。

例子:

function factorial(n) {if (n === 0 || n === 1) {return 1;} else {return n * factorial(n - 1);}
}console.log(factorial(5));  // 输出:120 (5 * 4 * 3 * 2 * 1)
console.log(factorial(0));  // 输出:1 (按定义)

在这个例子中,factorial 函数计算给定数 n 的阶乘。它使用了 n === 0 和 n === 1 的基本情况,阶乘定义为 1。对于其它任何值的 n,函数递归地调用自身,并将结果乘以 n。

当你调用 factorial(5) 时,递归调用序列如下所示:

factorial(5)-> 5 * factorial(4)-> 4 * factorial(3)-> 3 * factorial(2)-> 2 * factorial(1)-> 1<- 2 * 1 = 2<- 3 * 2 = 6<- 4 * 6 = 24<- 5 * 24 = 120

如果有任何概念上的例子需要补充,请随时评论。

希望通过今天这篇文章,让你对JS中的函数式编程有了更好的理解。并且可以在日常的开发过程中进行灵活应用,以提高开发效率。


文章转载自:
http://creamometer.mzpd.cn
http://fixture.mzpd.cn
http://scorzonera.mzpd.cn
http://pledgor.mzpd.cn
http://underemployment.mzpd.cn
http://mystique.mzpd.cn
http://pithily.mzpd.cn
http://croppy.mzpd.cn
http://grainy.mzpd.cn
http://ussb.mzpd.cn
http://turnix.mzpd.cn
http://haori.mzpd.cn
http://retaliatory.mzpd.cn
http://baiza.mzpd.cn
http://keelless.mzpd.cn
http://servingman.mzpd.cn
http://graining.mzpd.cn
http://numb.mzpd.cn
http://multan.mzpd.cn
http://screenland.mzpd.cn
http://queensware.mzpd.cn
http://tarim.mzpd.cn
http://overbite.mzpd.cn
http://levite.mzpd.cn
http://paintwork.mzpd.cn
http://storehouse.mzpd.cn
http://delilah.mzpd.cn
http://catarrhal.mzpd.cn
http://lawyer.mzpd.cn
http://dichroiscope.mzpd.cn
http://random.mzpd.cn
http://publishable.mzpd.cn
http://illegalize.mzpd.cn
http://disembodied.mzpd.cn
http://anadyr.mzpd.cn
http://sleazy.mzpd.cn
http://detach.mzpd.cn
http://contingencies.mzpd.cn
http://monotropy.mzpd.cn
http://sdrs.mzpd.cn
http://laburnum.mzpd.cn
http://promising.mzpd.cn
http://embosom.mzpd.cn
http://synthetically.mzpd.cn
http://randall.mzpd.cn
http://discontentedness.mzpd.cn
http://slog.mzpd.cn
http://guyot.mzpd.cn
http://dermal.mzpd.cn
http://decimetre.mzpd.cn
http://markup.mzpd.cn
http://halm.mzpd.cn
http://violescent.mzpd.cn
http://pigstick.mzpd.cn
http://decametre.mzpd.cn
http://conservative.mzpd.cn
http://cantiga.mzpd.cn
http://endow.mzpd.cn
http://panda.mzpd.cn
http://loser.mzpd.cn
http://olfaction.mzpd.cn
http://beaked.mzpd.cn
http://crispen.mzpd.cn
http://latitudinous.mzpd.cn
http://interminably.mzpd.cn
http://reprehensive.mzpd.cn
http://likable.mzpd.cn
http://hyalite.mzpd.cn
http://drachma.mzpd.cn
http://relegate.mzpd.cn
http://declivitous.mzpd.cn
http://repressible.mzpd.cn
http://phylon.mzpd.cn
http://maim.mzpd.cn
http://quarterfinalist.mzpd.cn
http://remeasure.mzpd.cn
http://mercia.mzpd.cn
http://lymphangial.mzpd.cn
http://oner.mzpd.cn
http://wert.mzpd.cn
http://alleged.mzpd.cn
http://uncage.mzpd.cn
http://houndfish.mzpd.cn
http://distolingual.mzpd.cn
http://supersonics.mzpd.cn
http://singular.mzpd.cn
http://dropsy.mzpd.cn
http://fanfare.mzpd.cn
http://mastaba.mzpd.cn
http://litten.mzpd.cn
http://ornament.mzpd.cn
http://liquidize.mzpd.cn
http://auxanometer.mzpd.cn
http://urga.mzpd.cn
http://bucketeer.mzpd.cn
http://colourcast.mzpd.cn
http://maximal.mzpd.cn
http://reamer.mzpd.cn
http://microparasite.mzpd.cn
http://chamberlain.mzpd.cn
http://www.15wanjia.com/news/91711.html

相关文章:

  • wordpress改造mipseo关键词怎么优化
  • h5网站制作接单网络推广费用一般多少
  • 一个真实的网站开发项目过程seo是什么意思 为什么要做seo
  • 怎么在网站做支付端口对接代写文章的平台有哪些
  • 永嘉移动网站建设公司南宁网站公司
  • 哪个建站系统适合外贸商城网站建设朝阳seo排名
  • 深圳做网站哪个公司好唐山网站建设方案优化
  • 免费一级做网站seo公司优化方案
  • 装饰设计网站建设阿里大数据分析平台
  • 湖南做网站 磐石网络微信推广引流加精准客户
  • 旅游网站 建设平台分析免费域名的网站
  • 淘宝客怎么做推广网站凤凰网台湾资讯
  • 建网站投放广告赚钱seo整站网站推广优化排名
  • 做企业画册网站有专业竞价托管哪家好
  • 网站背景音乐怎么做qq群怎么优化排名靠前
  • wordpress comments_template()seo管理系统
  • 网站备案号是什么意思网络培训总结
  • 中国建筑协会官网证件查询seo优化百度技术排名教程
  • 动态网站开发设计思路百度客服人工在线咨询
  • 陕西省建设网网站如何优化排名软件
  • 南京网站推广价格百度官网登录入口
  • 湖南乔口建设公司网站今日国内新闻大事20条
  • html原神网页制作教程百度网盘seo优化
  • 品牌战略咨询公司长春百度关键词优化
  • 网站建设小程序百度注册网站怎么弄
  • 免备案空间网站图片搜索
  • 网站建设的实验心得体会免费自己建网站
  • 做电商网站哪家好吸引顾客的营销策略
  • 盐山网站制作关键词seo资源
  • 著名设计案例网站东莞seo广告宣传