gpt4 book ai didi

Javascript 函数式编程 |功能

转载 作者:塔克拉玛干 更新时间:2023-11-02 22:12:17 24 4
gpt4 key购买 nike

我正在尝试使用对象数组进行函数式编程。

我想了解是否有更好更干净的方法来执行一系列根据条件取值和更新变量的函数。

就像使用全局范围的变量一样,这是不受欢迎的吗?无论如何我可以将狗的数量传递给“updateDogsAmt”函数吗?等等……

有没有更好的方法可以做到这一点?

我已经将这些功能划分为更新 DOM 和逻辑之间的功能。

演示:JSFIDDLE

    const animals = [
{name: 'Zack', type: 'dog'},
{name: 'Mike', type: 'fish'},
{name: 'Amy', type: 'cow'},
{name: 'Chris', type: 'cat'},
{name: 'Zoe', type: 'dog'},
{name: 'Nicky', type: 'cat'},
{name: 'Cherry', type: 'dog'}
]

let dogs = [];
function getDogs() {
//return only dogs
animals.map((animal) => {
if(animal.type === "dog") {
dogs.push(animal);
}
});
}
getDogs();

let dogsAmt = 0;
function getDogsAmt() {
//get dogs amount
dogsAmt = dogs.length;
}
getDogsAmt();

function updateDogsAmt() {
//update dom with dogs count
let dogsHTML = document.getElementById('dogs-amt');
dogsHTML.innerHTML = dogsAmt;
}
updateDogsAmt();

let otherAnimals = [];
function getOtherAnimals() {
//return other animals count
animals.map((animal) => {
if(animal.type != "dog") {
otherAnimals.push(animal);
}
});
}
getOtherAnimals();

let otherAnimalsAmt = 0;
function getOtherAnimalsAmt() {
otherAnimalsAmt = otherAnimals.length;
}
getOtherAnimalsAmt();

function updateOtherAnimalsAmt() {
//udate dom with other animals
let otherAmt = document.getElementById('other-amt');
otherAmt.innerHTML = otherAnimalsAmt;
}
updateOtherAnimalsAmt();

最佳答案

在函数式编程中,函数是的,这意味着:

  • 它们不会产生副作用(它们不会修改范围之外的变量)
  • 给定相同的输入,它们总是产生相同的输出

你定义的函数并不纯粹,因为它们

  • 在其范围之外修改变量
  • 返回不同的结果,这取决于范围之外的变量状态

所以这个函数不纯:

let dogsAmt = 0;
function getDogsAmt() {
// do something with dogs and modify dogsAmt
}

虽然这一个是纯粹的:

function getDogsAmt(dogs) {
// do something with dogs and return dogsAmt
}
let dogsAmt = getDogsAmt(dogs);

以函数式风格编写可以轻松重用代码。例如,在您的示例中,您只需要一个函数来分别计算动物数量和更新 DOM:

const animals = [
{name: 'Zack',type: 'dog'},
{name: 'Mike',type: 'fish'},
{name: 'Amy', type: 'cow'},
{name: 'Chris', type: 'cat'}
];

function getDogs(animals) {
//return only dogs
return animals.filter(animal => animal.type === "dog");
}

function getOtherAnimals(animals) {
//return other animals count
return animals.filter(animal => animal.type !== "dog");
}

function getAmt(animals) {
//get number of animals in the array
return animals.length;
}

function updateHTML(id, amount) {
//update dom
document.getElementById(id).innerHTML = amount;
}

updateHTML('dogs-amt', getAmt(getDogs(animals)));
updateHTML('other-amt', getAmt(getOtherAnimals(animals)));
<p>There are <span id="dogs-amt">0</span> dogs</p>
<p>There are <span id="other-amt">0</span> other animals</p>

都是纯的吗?

这段代码中的一个函数仍然不纯! updateHTML 接受两个参数,并始终返回 undefined。但在此过程中,它会产生副作用:它会更新 DOM!

如果您想解决基于不纯 函数手动更新 DOM 的问题,我建议您查看 React、Elm、Cycle.js 或 Vue.js 等库/框架 - 它们所有这些都使用了一个称为虚拟 DOM 的概念,它允许将整个 DOM 表示为 JS 数据结构,并为您负责将虚拟 DOM 与真实 DOM 同步。

JavaScript 函数式编程

函数式语言(例如 Haskell、Lisp、Clojure、Elm)迫使您编写纯函数,并在您的背景更多地是面向过程或面向对象的编程时引入许多令人费解的概念。在我看来,JavaScript 是一种“偶然发现”函数式编程的优秀语言。虽然乍一看它看起来像 Java,但当您仔细观察时,JS 与 Lisp 有更多共同点。尝试理解闭包和原型(prototype)继承之类的东西,而不是像 Java 一样尝试编写 JS,这对我帮助很大。 (在这方面的一个很好的阅读:The Two Pillars of JavaScript)

对于函数式 JavaScript 的后续步骤,我建议您

  • 尽可能在脚本中使用较少的状态(不要再let)
  • 了解并使用 Array 原型(prototype)上的函数,例如 ma​​pfilterreduce ( see e.g. this article )、some、any、.. .
  • 只写纯函数,不能写的时候要谨慎

在您对此更加熟悉之后,您可以开始一点一点地处理更高级的函数概念(高阶函数、偏应用、柯里化(Currying)、不可变性、单子(monad)、可观察对象/函数响应式(Reactive)编程)。 JavaScriptLand 中一些有趣的库是

关于Javascript 函数式编程 |功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40675740/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com