JavaScript进阶6之函数式编程与ES6ESNext规范
函数式编程
- 柯里化curry
- curry
- compose
- 示例:
- 简化版
- 展开写:
- debug
- 示例一:
- 示例二:
- 模板字符串
- css in js方案
- 箭头函数
- 问题
- 生成器 generator
- 应用场景
- 反射 Reflect
柯里化curry
compose是curry的应用
在 lodash/fp
underscore
ramba
curry
function curry(fn){// 统计传入函数的参数个数const len=fn.length// 函数命名为的后面重复调用return function curried(...args){// 当传入的参数个数大于等于函数需要的参数个数的时候,则执行函数if(args.length>=len){return fn.apply(this,args)}else{// 否则返回函数并且接收后面传入的参数return function(...args2){// 执行回调curried函数,将参数合并传入下一次回调中return curried.apply(this,args.concat(args2))}}}
}
compose
两个函数组合:
function compose(f,g){return function(x){return f(g(x))}
}
不确定个数函数组合:
// 传入多个函数
function compose(...fns){// 当个数if(fns.length===0){// console.log("-----等于0----");// compose不传参数的时候,返回的是一个函数,这个函数传的参数都返回return (args)=>args}if(fns.length===1){// console.log("----等于1-----");// compose传入一个参数的话,就返回这个函数return fns[0]}// compose传入两个及两个以上函数的时候,使用reduce将作为参数的函数从右往左执行return fns.reduce((pre,cur)=>(...args)=>pre(cur(...args)))
}
示例:
简化版
var compose=(f,g)=>(x)=>f(g(x))
const curry=require('lodash').curryvar toUpperCase=curry(function(str){return str.toUpperCase()
})var head=curry(function(x){return x[0]
})
var initials=function(name){return name.split(' ').map(compose(toUpperCase,head)).join('. ')
}
console.log(initials('hunter stockton thompson'))

展开写:
function curry(fn){// 统计传入函数的参数个数const len=fn.length// 函数命名为的后面重复调用return function curried(...args){// 当传入的参数个数大于等于函数需要的参数个数的时候,则执行函数if(args.length>=len){return fn.apply(this,args)}else{// 否则返回函数并且接收后面传入的参数return function(...args2){// 执行回调curried函数,将参数合并传入下一次回调中return curried.apply(this,args.concat(args2))}}}
}
// 传入多个函数
function compose(...fns){// 当个数if(fns.length===0){// console.log("-----等于0----");// compose不传参数的时候,返回的是一个函数,这个函数传的参数都返回return (args)=>args}if(fns.length===1){// console.log("----等于1-----");// compose传入一个参数的话,就返回这个函数return fns[0]}// compose传入两个及两个以上函数的时候,使用reduce将作为参数的函数从右往左执行return fns.reduce((pre,cur)=>(...args)=>pre(cur(...args)))
}var head=curry(function(x){return x[0]
})
var split=curry(function(rules,str){return str.split(rules)
})
var toUpperCase=curry(function(str){return str.toUpperCase()
})
var map=curry(function(f,arr){return arr.map(f)
})
var join=curry(function(f,arr){return arr.join(f)
})
var initials=compose(join('. '),map(compose(toUpperCase,head)),split(' '))console.log(initials('hunter stockton thompson'))

debug
示例一:
const curry=require('lodash').curryvar reverse=curry(function(arr){return arr.reverse()
})
var map=curry(function(f,arr){return arr.map(f)
})
var angry=curry(function(str){return str.toUpperCase()+"!"
})const compose=function(...fns){if(fns.length===0) return (args)=>argsif(fns.length===1) return fns[0]return fns.reduce((pre,cur)=>(...args)=>pre(cur(...args)))
}// var latin=compose(map,angry,reverse) //错误执行,angry接收的是一个字符串,// 但是reverse执行完后的结果是数组,传给angry会报错,所以应该把angry当做参数传给map用作map的规则才对
var latin=compose(map(angry),reverse)
console.log(latin(['frog','eyes']))

示例二:
const curry=require('lodash').curryfunction compose(...fns){if(fns.length===0) return (args)=>argsif(fns.length===1) return fns[0]return fns.reduce((pre,cur)=>(...args)=>pre(cur(...args)))
}var replace=curry(function(what,replacement,str){return str.replace(what,replacement)
})var split=curry(function(f,str){return str.split(f)
})var toLower=curry(function(x){return x.toLowerCase()
})
var join=curry(function(f,arr){return arr.join(f)
})
var map=curry(function(f,arr){return arr.map(f)
})// var dasherize=compose(join('-',toLower,split(' '),replace(/\s{2,}/ig, ' ')))
// 报错,由于toLower接收的是字符串而不是数组,所以应该先用map调用一下他
var dasherize=compose(join('-'),map(toLower),split(' '),replace(/\s{2,}/ig, ' '))console.log(dasherize('The world is a vampire'));

模板字符串
css in js方案
题外话:
建议大家往react方向学,react技术点很多,选择很多
比如:
样式体系:
- less,scss,其实目前看有点过时了
现在主流的样式体系方案:
- module css,中规中矩的
- css in js,运行时的开销,性能稍差
- tailwind css,极致性能
如果要做 SSR 服务端渲染,
一方面,css in js 相对不好处理,但是有对应的方案, 而且比较符合正常开发者定义组件,维护对应的内容
另一方面,官方推荐的是 module css,tailwind css
// 用在 css in js 的方案里const styled = {div: function (strings) {const divDom = document.createElement("div"); //nodejs不能执行strings.forEach((str) => {const s = str.split(";");for (const kv of s) {const [key, value] = kv.split(":");divDom.style[key] = value; //nodejs不能执行console.log("🚀 ~ styled.key:", key, value);}});// return react component //React中返回return divDom;},h1: function (...args) {console.log("🚀 ~ styled.args:", args);},
};
const Div = styled.div`color: red;font-size: 20px;
`;
如果要了解某个代码在编译器中处理完后得到什么内容的话,可以使用babel去看
链接: link
看具体原理,内部具体是怎么做的

箭头函数
问题
- 不能定义构造器,不能new
- this指向的是外部的作用域
- 没有arguments
- this不能绑定(apply,bind,call)

生成器 generator
应用场景
大家对于异步的处理是不是都基于 async、await来做的?
// async await的实现,就是借助 promise + generator
const getData = async ()=>{const res=Promise.resolve(1)return res
}async function test(){await getData()
}

反射 Reflect
Reflect.set(target, key, value, receiver);
重点看看 receiver,接收者决定this指向
// 用来劫持对象的逻辑const handler = {get(target, key, receiver) {console.log("get", key, receiver);// 值的获取,是不是就是我们所谓的依赖收集// track()// return target[key];return Reflect.get(target, key);},set(target, key, value, receiver) {console.log("set", value);// target[key] = value;Reflect.set(target, key, value, receiver);// 值的设置就是我们所谓的更新操作// trigger()},
};// Vue3.0的响应式原理const target = {a: 1,get b() {return this.a;},
};// 劫持这个 target 对象的熟悉
const reactiveTarget = new Proxy(target, handler);
console.log("reactiveTarget:", reactiveTarget.a, reactiveTarget.b);reactiveTarget.a = 10;console.log("reactiveTarget:", reactiveTarget.a, reactiveTarget.b);console.log(Reflect.get(target, "a"));
console.log(Reflect.get(target, "b", { b: "null111", a: "null222" }));


o?.a是什么意思
在JavaScript中,o?.a是一种新的语法,称为可选链操作符(Optional Chaining Operator)。这个操作符用于在访问对象属性时进行安全的操作,即使对象的某个属性不存在或者为null或undefined,也不会导致运行时错误。
具体来说,o?.a表示如果对象o存在且具有属性a,则返回o.a的值;如果对象o不存在或者属性a不存在,则返回undefined,而不会抛出错误。
这种语法的引入使得代码更加简洁并且更安全,特别是在处理深层嵌套的对象属性时。
相关文章:
JavaScript进阶6之函数式编程与ES6ESNext规范
函数式编程 柯里化currycurrycompose示例:简化版展开写: debug示例一:示例二: 模板字符串css in js方案 箭头函数问题 生成器 generator应用场景 反射 Reflect 柯里化curry compose是curry的应用 在 lodash/fp underscore ramba …...
AcWing 1381. 阶乘
解题思路 最后一位数相乘的变化。注意:为什么不是ss%10,如果12 * 15, 12的最后一位时2, * 1530,则为3,问题是12*15180,为8,两 者不符,说明ss%10中的10要多加0. import j…...
Leetcode 394. 字符串解码
心路历程: 这道题看到括号直接想到栈,五分钟新题直接秒了,一开始以为需要两个栈分别存储数字和非数字,后来发现一个栈就够了,思路如图: 这道题考察的应该是队栈这两种数据结构的转换,因为每次…...
LeetCode - 1702. 修改后的最大二进制字符串
文章目录 解析AC CODE 题目链接:LeetCode - 1702. 修改后的最大二进制字符串 解析 详细题解:贪心,简洁写法(Python/Java/C/Go/JS/Rust) 思路很牛b。 简单来说我们需要想办法将0配对,将其变为10࿰…...
虹科Pico汽车示波器 | 免拆诊断案例 | 2011款东风悦达起亚K5车发动机偶尔起动困难
一、故障现象 一辆2011款东风悦达起亚K5车,搭载G4KD发动机,累计行驶里程约为24.5万km。车主反映,第1次起动发动机时偶尔无法起动着机,第2次能够正常起动着机,但发动机故障灯异常点亮。为此在其他维修厂维修过…...
Docker- Redis
博文目录 文章目录 说明前置命令 说明 Docker Hub Redis 数据卷数据卷印射在容器内的路径redis/data 容器内的路径说明/data数据目录/data/redis.conf配置文件 前置 在 GitHub 找一份 redis.conf 配置文件, 放到卷 redis 中, 按需修改 # bind 127.0.0.1 # 解除只允许环回地…...
Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单视频处理实战案例 之八 简单视频素描效果
Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单视频处理实战案例 之八 简单视频素描效果 目录 Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单视频处理实战案例 之八 简单视频素描效果 一、简单介绍 二、简单指定视频某片段快放效果实现原理 三、简单指定视频某…...
数据结构——线性表(链式存储结构)
语言:C语言软件:Visual Studio 2022笔记书籍:数据结构——用C语言描述如有错误,感谢指正。若有侵权请联系博主 一、线性表的逻辑结构 线性表是n个类型相同的数据元素的有限序列,对n>0,除第一元素无直接…...
面试算法-169-二叉树的中序遍历
题目 给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。 示例 1: 输入:root [1,null,2,3] 输出:[1,3,2] 解 class Solution {public List<Integer> inorderTraversal(TreeNode root) {List<Integer> resul…...
计算机视觉——引导APSF和梯度自适应卷积增强夜间雾霾图像的可见性算法与模型部署(C++/python)
摘要 在夜间雾霾场景中,可见性经常受到低光照、强烈光晕、光散射以及多色光源等多种因素的影响而降低。现有的夜间除雾方法常常难以处理光晕或低光照条件,导致视觉效果过暗或光晕效应无法被有效抑制。本文通过抑制光晕和增强低光区域来提升单张夜间雾霾…...
git bash用法-批量修改文件名
在win系统上安装git bash可以使用命令行模式操作,比较方便 1.原始文件名 2.代码 for file in *3utr*; do mv "$file" "$(echo "$file" | sed s/3utr/5utr/)"; done3.修改后的文件名...
分布式社交媒体:探索Web3对社交媒体的改变
在数字化时代,社交媒体已成为人们日常生活中不可或缺的一部分。然而,传统的社交媒体平台往往由中心化的机构或公司掌控,用户的数据和内容受到限制,引发了一系列的隐私和安全问题。随着区块链技术的发展,分布式社交媒体…...
vue的监视属性
目录 1. 场景引入2. watch3. 深度监视4. 监视属性简写5. 小结 1. 场景引入 在实际开发中,有时开发者需要根据某个属性的变化,做出相应的决策,因此Vue为开发者提供了watch.这一监视属性,用于实现此类需求。比如下面这个场景&…...
外包干了15天,技术倒退明显
先说情况,大专毕业,18年通过校招进入湖南某软件公司,干了接近6年的功能测试,今年年初,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落! 而我已经在一个企业干了四年的功能…...
防止邮箱发信泄露服务器IP教程
使用QQ邮箱,网易邮箱,189邮箱,新浪邮箱,139邮箱可能会泄露自己的服务器IP。 泄露原理:服务器通过请求登录SMTP邮箱服务器接口,对指定的收件人发送信息。 建议大家使用商业版的邮箱,比如阿里云邮箱发信等 防止邮件发信漏源主要关注的是确保邮件…...
鸿蒙HarmonyOS开发实战:【分布式音乐播放】
介绍 本示例使用fileIo获取指定音频文件,并通过AudioPlayer完成了音乐的播放完成了基本的音乐播放、暂停、上一曲、下一曲功能;并使用DeviceManager完成了分布式设备列表的显示和分布式能力完成了音乐播放状态的跨设备分享。 本示例用到了与用户进行交…...
【iOS ARKit】App 中嵌入 AR Quick Look
AR Quick Look 功能强大,但在应用中嵌入并使用它实现 AR体验却非常简单,如其他所有QuickLook使用一样,简单到只需要提供一个文件名就可以达到目标。 AR Quick Look 支持.usdz 和.reality 两种格式文件,如果在 Xcode 工程中引入了 …...
【Web开发】jquery图片放大镜效果制作变焦镜头图片放大
jquery图片放大镜效果制作变焦镜头图片放大实现 整体步骤流程: 1. 前端html实现 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns"…...
RTC实时显示时间(备份电源 备份域的作用)
RTC初始化配置 系统复位后,可通过 PWR 电源控制寄存器 (PWR_CR) 的 DBP 位保护 RTC 寄存器以防止 非正常的写访问。必须将 DBP 位置 1 才能使能 RTC 寄存器的写访问。 上电复位后,所有 RTC 寄存器均受到写保护。通过向写保护寄存器 (RTC_WPR) 写入一个…...
【YOLOv9】完胜V8的SOTA模型Yolov9(论文阅读笔记)
官方论文地址: 论文地址点击即可跳转 官方代码地址: GitCode - 开发者的代码家园 官方代码地址点击即可跳转 1 总述 当输入数据经过各层的特征提取和变换的时候,都会丢失一定的信息。针对这一问题:...
龙虎榜——20250610
上证指数放量收阴线,个股多数下跌,盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型,指数短线有调整的需求,大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的:御银股份、雄帝科技 驱动…...
装饰模式(Decorator Pattern)重构java邮件发奖系统实战
前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...
ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...
UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...
laravel8+vue3.0+element-plus搭建方法
创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...
人机融合智能 | “人智交互”跨学科新领域
本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...
【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)
本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...
PHP 8.5 即将发布:管道操作符、强力调试
前不久,PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5!作为 PHP 语言的又一次重要迭代,PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是,借助强大的本地开发环境 ServBay&am…...
水泥厂自动化升级利器:Devicenet转Modbus rtu协议转换网关
在水泥厂的生产流程中,工业自动化网关起着至关重要的作用,尤其是JH-DVN-RTU疆鸿智能Devicenet转Modbus rtu协议转换网关,为水泥厂实现高效生产与精准控制提供了有力支持。 水泥厂设备众多,其中不少设备采用Devicenet协议。Devicen…...
