• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • dedecms
  • ecshop
  • z-blog
  • UcHome
  • UCenter
  • drupal
  • WordPress
  • 帝国cms
  • phpcms
  • 动易cms
  • phpwind
  • discuz
  • 科汛cms
  • 风讯cms
  • 建站教程
  • 运营技巧
您的位置:首页 > CMS教程 >建站教程 > 一起聊聊JavaScript函数式编程

一起聊聊JavaScript函数式编程

作者:站长图库 字体:[增加 减小] 来源:互联网

站长图库向大家介绍了JavaScript函数式,JavaScript编程等相关知识,希望对您有所帮助

本篇文章给大家带来了关于javascript的相关知识,其中主要介绍了函数式编程的相关问题,函数式编程可以理解为,以函数作为主要载体的编程方式,用函数去拆解、抽象一般的表达式,希望对大家有帮助。


一起聊聊JavaScript函数式编程


看过许多关于函数式编程的讲解,但是其中大部分是停留在理论层面,还有一些是仅针对 Haskell 等纯函数式编程语言的。而本文旨在聊一聊我眼中的函数式编程在 JavaScript 中的具体实践,之所以是 “我眼中的” 即我所说的仅代表个人观点,可能和部分 严格概念 是有冲突的。

本文将略去一大堆形式化的概念介绍,重点展示在 JavaScript 中到底什么是函数式的代码、函数式代码与一般写法有什么区别、函数式的代码能给我们带来什么好处以及常见的一些函数式模型都有哪些。

我理解的函数式编程

我认为函数式编程可以理解为,以函数作为主要载体的编程方式,用函数去拆解、抽象一般的表达式

与命令式相比,这样做的好处在哪?主要有以下几点:

语义更加清晰

可复用性更高

可维护性更好

作用域局限,副作用少

基本的函数式编程

下面例子是一个具体的函数式体现


Javascript代码

// 数组中每个单词,首字母大写  // 一般写法  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);   // 函数式写法一  function upperFirst(word) {  return word[0].toUpperCase() + word.slice(1);  }  function wordToUpperCase(arr) {  return arr.map(upperFirst);  }  console.log(wordToUpperCase(['apple', 'pen', 'apple-pen']));   // 函数式写法二  console.log(arr.map(['apple', 'pen', 'apple-pen'], word => word[0].toUpperCase() + word.slice(1)));

当情况变得更加复杂时,表达式的写法会遇到几个问题:

表意不明显,逐渐变得难以维护

复用性差,会产生更多的代码量

会产生很多中间变量

函数式编程很好的解决了上述问题。首先参看 函数式写法一,它利用了函数封装性将功能做拆解(粒度不唯一),并封装为不同的函数,而再利用组合的调用达到目的。这样做使得表意清晰,易于维护、复用以及扩展。其次利用 高阶函数,Array.map 代替 for…of 做数组遍历,减少了中间变量和操作。

而 函数式写法一 和 函数式写法二 之间的主要差别在于,可以考虑函数是否后续有复用的可能,如果没有,则后者更优。


链式优化

从上面 函数式写法二 中我们可以看出,函数式代码在写的过程中,很容易造成 横向延展,即产生多层嵌套,下面我们举个比较极端点的例子。

Javascript代码

// 计算数字之和  // 一般写法  console.log(1 + 2 + 3 - 4)   // 函数式写法  function sum(a, b) {    return a + b;  }  function sub(a, b) {    return a - b;  }  console.log(sub(sum(sum(1, 2), 3), 4);

本例仅为展示 横向延展 的比较极端的情况,随着函数的嵌套层数不断增多,导致代码的可读性大幅下降,还很容易产生错误。 

在这种情况下,我们可以考虑多种优化方式,比如下面的 链式优化 。 

// 优化写法 (嗯,你没看错,这就是 lodash 的链式写法) Javascript代码 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());

这样改写后,结构会整体变得比较清晰,而且链的每一环在做什么也可以很容易的展现出来。函数的嵌套和链式的对比还有一个很好的例子,那就是 回调函数 和 Promise 模式。

Javascript代码

// 顺序请求两个接口   // 回调函数  import $ from 'jquery';  $.post('a/url/to/target', (rs) => {    if(rs){      $.post('a/url/to/another/target', (rs2) => {        if(rs2){          $.post('a/url/to/third/target');        }      });    }  });   // Promise  import request from 'catta';  // catta 是一个轻量级请求工具,支持 fetch,jsonp,ajax,无依赖  request('a/url/to/target')  .then(rs => rs ? $.post('a/url/to/another/target') : Promise.reject())  .then(rs2 => rs2 ? $.post('a/url/to/third/target') : Promise.reject());

随着回调函数嵌套层级和单层复杂度增加,它将会变得臃肿且难以维护,而 Promise 的链式结构,在高复杂度时,仍能纵向扩展,而且层次隔离很清晰。

常见的函数式编程模型

闭包(Closure)

可以保留局部变量不被释放的代码块,被称为一个闭包

闭包的概念比较抽象,相信大家都或多或少知道、用到这个特性

那么闭包到底能给我们带来什么好处?

先来看一下如何创建一个闭包:

Javascript代码

// 创建一个闭包  function makeCounter() {    let k = 0;       return function() {      return ++k;    };  }  const counter = makeCounter();  console.log(counter());  // 1  console.log(counter());  // 2

makeCounter 这个函数的代码块,在返回的函数中,对局部变量 k ,进行了引用,导致局部变量无法在函数执行结束后,被系统回收掉,从而产生了闭包。而这个闭包的作用就是,“保留住“ 了局部变量,使内层函数调用时,可以重复使用该变量;而不同于全局变量,该变量只能在函数内部被引用。

换句话说,闭包其实就是创造出了一些函数私有的 ”持久化变量“。

所以从这个例子,我们可以总结出,闭包的创造条件是:

存在内、外两层函数

内层函数对外层函数的局部变量进行了引用

闭包的用途

闭包的主要用途就是可以定义一些作用域局限的持久化变量,这些变量可以用来做缓存或者计算的中间量等等。

Javascript代码

// 简单的缓存工具  // 匿名函数创造了一个闭包  const cache = (function() {    const store = {};         return {      get(key)
  


 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 一起聊聊JavaScript函数式编程

相关文章

  • Photoshop从零开始设计漂亮的网页模板
  • php中如何获取当前的函数名
  • PHP存入mysql乱码怎么办
  • 关键词组合的SEO优化策略
  • Photoshop设计书法人像前后期创作分享
  • JavaScript事件之事件冒泡与时间捕获(总结分享)
  • Photoshop制作超逼真缝线效果
  • PHP保存数组到数据库
  • Node.js深入学习之浅析require函数中怎么添加钩子
  • 20款wordpress的SEO插件

文章分类

  • dedecms
  • ecshop
  • z-blog
  • UcHome
  • UCenter
  • drupal
  • WordPress
  • 帝国cms
  • phpcms
  • 动易cms
  • phpwind
  • discuz
  • 科汛cms
  • 风讯cms
  • 建站教程
  • 运营技巧

最近更新的内容

    • Javascript获取日期的方法是什么
    • Photoshop设计大气的淘宝年终促销海报
    • 消除if else, 让你的代码看起来更优雅
    • Laravel如何批量更新多条记录(防SQL注入)
    • 帝国CMS关闭前台不需要功能方法
    • Photoshop绘制质感IE图标教程
    • 如何解决LayUI时间控件闪退问题
    • WordPress 5.0 如何换回原有”Classic Editor”编辑器?
    • JavaScript中解析parseInt()的怪异行为
    • 帝国CMS灵动标签调用当天更新的标题文字显示红色其他颜色变成灰色

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有