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 总述 当输入数据经过各层的特征提取和变换的时候,都会丢失一定的信息。针对这一问题:...
idea大量爆红问题解决
问题描述 在学习和工作中,idea是程序员不可缺少的一个工具,但是突然在有些时候就会出现大量爆红的问题,发现无法跳转,无论是关机重启或者是替换root都无法解决 就是如上所展示的问题,但是程序依然可以启动。 问题解决…...
深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...
shell脚本--常见案例
1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...
vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...
电脑插入多块移动硬盘后经常出现卡顿和蓝屏
当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时,可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案: 1. 检查电源供电问题 问题原因:多块移动硬盘同时运行可能导致USB接口供电不足&#x…...
力扣-35.搜索插入位置
题目描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...
以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...
如何更改默认 Crontab 编辑器 ?
在 Linux 领域中,crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用,用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益,允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...
站群服务器的应用场景都有哪些?
站群服务器主要是为了多个网站的托管和管理所设计的,可以通过集中管理和高效资源的分配,来支持多个独立的网站同时运行,让每一个网站都可以分配到独立的IP地址,避免出现IP关联的风险,用户还可以通过控制面板进行管理功…...
基于PHP的连锁酒店管理系统
有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发,数据库mysql,前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...
