js中的函数式编程
函数是javascript中非常重要的一部分,用途也非常的多,可作为参数、返回值、回调等等,下面有一些函数式编程的重要概念和定义
纯函数
纯函数属于程序设计的名词,其它语言中也是存在的,而在javascript中,符合以下规则即为纯函数。
- 函数有相同的输入,必定有相同的输出
- 函数的输出仅与输入有关,与其他隐藏信息无关
- 不得产生任何的副作用,如 触发事件等
副作用:除了返回函数值以外,还对调用函数产生了其他的影响,如修改全局变量、修改参数或者改变外部存储。
以下几个示例来区分一下纯函数和非纯函数
1、数组方法
var arr1 = [1, 2, 3, 4]
var arr2 = [10, 20, 30, 40]
const newArr1 = arr1.splice(1, 3)
const newArr2 = arr2.slice(1, 3)
console.log(arr1, newArr1) // [1] [2, 3, 4]
console.log(arr2, newArr2) // [10, 20, 30, 40] [20, 30]
splice 通过下标值和长度操作原数组本身,修改了入参,所以不是纯函数。
slice 通过下标值截取数组,返回一个新的数组,没有副作用,是纯函数。
2、修改入参
var obj = { name: 'alice' }
function foo(info) {
info.name = 'kiki'
return info
}
foo(obj)
function bar(info) {
return {
...info,
name: 'kiki'
}
}
bar(obj)
上面两个函数的作用都是返回一个新的对象,但foo修改了入参,所以foo不是纯函数,bar没有产生任何副作用,满足纯函数的定义。
使用纯函数在开发当中具有一些优点
- 不用考虑传入的参数是否已经发生了变化
- 不用考虑函数的操作是否会修改全局、外部的一些变量
这样函数的功能就更加的单一和纯净,可以放心的编写和使用
柯里化
通过函数返回函数的方式,实现多次接收参数并进行统一处理的函数编码形式
function sum(a, b, c) {
return a + b + c
}
// 柯里化写法
function add(a) {
return function (b) {
return function (c) {
return a + b + c
}
}
}
sum(1, 2, 3)
add(1)(2)(3)
以上两个函数的执行结果相同,但是调用方式不同,使用柯里化的优点在于使每一个函数的功能更加单一,及逻辑复用
function foo(type, time, message){
console.log(`${type}:${[time]}:${message}`)
}
foo('error', '2021/10/24', '接口返回数据异常')
foo('error', new Date(), '页面显示错误')
// 柯里化写法
function log(type) {
return function (time) {
return function (message) {
console.log(`${type}:${[time]}:${message}`)
}
}
}
var error = log('error')
error('2021/10/24')('接口返回数据异常')
error(new Date())('页面显示错误')
如以上柯里化代码,复用了【获取类型】部分的函数
组合函数
组合函数不是一种函数类型,只是创建一个新函数将多种功能的函数合并起来
function mul(m) {
return m * 2
}
function square(n) {
return n * n
}
// 组合函数
function compose(m, n) {
return function (i) {
return m(n(i))
}
}
var fn = compose(mul, square)
console.log(fn(5))
通过组合函数,就可以将不同功能的函数组合使用
with语句
with语句可以创建一个独立的作用域
with语句的语法是 with(){},with小括号内需要传递一个值,一般为对象,with语句内的变量会从这个小括号里先查找
var message = 'global'
var obj = { name: 'alice', message: 'obj' }
function foo() {
console.log(message)
with (obj) {
console.log(message)
}
}
foo()
以上代码的执行结果如下
目前with语句已经不推荐使用了
eval
eval用于解析字符串及执行代码
var str = "var message = 'global'; console.log(message)"
eval(str)
以上代码执行完成会在控制台上输出 global
目前已经不推荐使用eval,从上述代码,我们可以看出它存在的问题
- 可读性非常差,也不便于维护
- eval字符串很可能会在执行的过程中被篡改,容易遭到攻击
- js代码在解析的过程中可以经过js引擎优化,如果是字符串,就没办法优化
严格模式
在全局或者函数中通过 "use strict" 来开启严格模式,严格模式下,不允许编写一些松散的代码,浏览器会对代码进行更严格的检测
严格模式对javascript语义做了一些限制
1、严格模式通过【抛出错误】来消除一些原有的【静默】错误
静默错误:比如定义变量没有关键字声明,如 num = 1
2、严格模式在js引擎在执行代码的时候可以进行更多的优化(不需要对特殊的语法进行处理)
如以下代码,通过属性描述符定义name属性为不可修改
var obj = {}
Object.defineProperty(obj, "name", { writable: false })
obj.name = "alice"
非严格模式直接忽略赋值,严格模式下会报错
3、严格模式禁用了在ECMAScript未来版本可能会定义的一些语法
如:
关键字 function var new
保留字 class let const (ES5以前)
保留字在未来有可能升级为关键字
非严格模式下以前可以使用保留字作为变量如var let = "abc"
严格模式下会报错
具体来说,严格模式做了以下限制
1、无法意外的创建全局变量
在非严格模式下,没有通过关键字定义的变量会被添加到全局
严格模式下这样的代码执行会抛出异常 message is not defined
message = "hello"
2、严格模式会使引起静默失败的赋值操作抛出异常
静默失败:silently fail,不报错也没有任何效果
非严格模式下不报错,严格模式下直接抛出异常 Cannot create property 'message' on boolean 'true'
true.name = "alice"
3、严格模式下删除不可删除的属性会抛出异常
非严格模式下不报错,忽略删除操作,严格模式下直接抛出异常 Cannot delete property 'address' of #
js中的函数式编程的更多相关文章
- 可爱的 Python : Python中的函数式编程,第三部分
英文原文:Charming Python: Functional programming in Python, Part 3,翻译:开源中国 摘要: 作者David Mertz在其文章<可爱的 ...
- Java 中的函数式编程(Functional Programming):Lambda 初识
Java 8 发布带来的一个主要特性就是对函数式编程的支持. 而 Lambda 表达式就是一个新的并且很重要的一个概念. 它提供了一个简单并且很简洁的编码方式. 首先从几个简单的 Lambda 表达式 ...
- C#中的函数式编程:序言(一)
学了那么久的函数式编程语言,一直想写一些相关的文章.经过一段时间的考虑,我决定开这个坑. 至于为什么选择C#,在我看来,编程语言分三类:一类是难以进行函数式编程的语言,这类语言包括Java6.C语言等 ...
- (数据科学学习手札48)Scala中的函数式编程
一.简介 Scala作为一门函数式编程与面向对象完美结合的语言,函数式编程部分也有其独到之处,本文就将针对Scala中关于函数式编程的一些常用基本内容进行介绍: 二.在Scala中定义函数 2.1 定 ...
- Apache Beam中的函数式编程理念
不多说,直接上干货! Apache Beam中的函数式编程理念 Apache Beam的编程范式借鉴了函数式编程的概念,从工程和实现角度向命令式妥协. 编程的领域里有三大流派:函数式.命令式.逻辑式. ...
- C#中的函数式编程:递归与纯函数(二) 学习ASP.NET Core Razor 编程系列四——Asp.Net Core Razor列表模板页面
C#中的函数式编程:递归与纯函数(二) 在序言中,我们提到函数式编程的两大特征:无副作用.函数是第一公民.现在,我们先来深入第一个特征:无副作用. 无副作用是通过引用透明(Referential ...
- C#中面向对象编程中的函数式编程详解
介绍 使用函数式编程来丰富面向对象编程的想法是陈旧的.将函数编程功能添加到面向对象的语言中会带来面向对象编程设计的好处. 一些旧的和不太老的语言,具有函数式编程和面向对象的编程: 例如,Smallta ...
- 通过代数,数字,欧几里得平面和分形讨论JavaScript中的函数式编程
本文是对函数式编程范式的系列文章从而拉开了与以下延续一个. 介绍 在JavaScript中,函数只是对象.因此,可以构造函数,作为参数传递,从函数返回或分配给变量.因此,JavaScript具有一流的 ...
- Java经典类库-Guava中的函数式编程讲解
如果我要新建一个java的项目,那么有两个类库是必备的,一个是junit,另一个是Guava.选择junit,因为我喜欢TDD,喜欢自动化测试.而是用Guava,是因为我喜欢简洁的API.Guava提 ...
- C#中的函数式编程
在函数式编程中,可以把函数看作数据.函数也可以作为参数,函数还可以返回函数.比如,LINQ就是基于函数式编程的. 两个例子引出函数式编程 语句式编程可能这样写: string result; ) { ...
随机推荐
- JavaScript封装大全
JavaScript封装大全-持续更新 Ajax封装 // 使用该封装需注意 // Ajax(method(默认GET), url(网址 必传), success(res){(成功时数据处理函数 必传 ...
- 理解 React 中的 useEffect、useMemo 与 useCallback
useEffect 先理解 useEffect 有助于学习 useMemo 和 useCallback.因为 useMemo 和 useCallback 的实现实际上都是基于 useEffect 的. ...
- 【Visual C#】基于《斗鱼弹幕服务器第三方接入协议v1.6.2》实现斗鱼弹幕服务器接入
最近在给某个主播开发斗鱼直播间辅助工具,为了程序的高效稳定,也搜索了大量的资料,经过大量什么百度,谷歌搜索... 虽然有很多Python的脚本及JS脚本实现了拉取斗鱼弹幕信息,但是这些年来的开发职业病 ...
- jenkins的安装和配置(flask结合jenkins半自动化部署流程)
jenkins在虚拟机中安装 1.1 背景介绍 Jenkins 是一款流行的开源持续集成(Continuous Integration)工具,广泛用于项目开发,具有自动化构建.测试和部署等功能. Je ...
- 2021-08-13:给定一个每一行有序、每一列也有序,整体可能无序的二维数组 ,在给定一个正数k,返回二维数组中,最小的第k个数。
2021-08-13:给定一个每一行有序.每一列也有序,整体可能无序的二维数组 ,在给定一个正数k,返回二维数组中,最小的第k个数. 福大大 答案2021-08-13: 二分法. 代码用golang编 ...
- vue全家桶进阶之路47:Vue3 Axios拦截器封装成request文件
可以将Axios拦截器封装成一个单独的request文件,以便在整个应用程序中重复使用. 以下是一个示例,展示如何将Axios拦截器封装成一个request文件: 1.创建一个名为request.js ...
- 巧用OpenSSH进行域内权限维持
最近在Windows服务器上安装OpenSSH,意外发现了一个很有意思的技巧,可用来做域内权限维持,废话不多说,直接上步骤. 01.利用方式 (1)在已经获得权限的Windows服务器上,使用msie ...
- hello-iot
iot,internet of things 环境搭建 使用真实环境 Single-board computer - Raspberry Pi Arduino - Wio Terminal 或者虚拟环 ...
- 海量数据运维要给力,GaussDB(for Cassandra)来助力
摘要:应用运维管理平台(AOM)和Cassandra是两个不可分割的组成部分,它们共同构成了一个高效的解决方案,可以帮助企业在应用运维业务上取得巨大的优势.在这篇文章中,我们将介绍AOM和Cassan ...
- .Net Aspose.Words 生成Word文档
.Net Aspose.Words 生成Word文档 在开发WinForm项目中,有一需求要生成Word文档,百度学习,记录一下实现方法 NuGet包,找到 Aspose.Words 安装 21.8. ...