关于javascript:js中的函数式编程

33次阅读

共计 3839 个字符,预计需要花费 10 分钟才能阅读完成。

函数是 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 #<Object>

var user = {name: 'alice'}
Object.defineProperty(user, 'address', {value: '上海'})
delete user.address

4、严格模式不容许函数参数有雷同的名称
非严格模式下执行函数,最终输入 3,2,3,严格模式下抛出异样 SyntaxError: Duplicate parameter name not allowed in this context

"use strict"
function foo(a, b, a) {console.log(a, b, a)
}
foo(1, 2, 3)

5、不容许 0 的八进制语法
非严格模式下,0 结尾的数字可代表八进制,严格模式下,定义 0 结尾的数字会抛出异样。Octal literals are not allowed in strict mode.
严格模式下能够别的形式定义进制,如 0o(八进制)、0x(十六进制),0b(二进制)

var num = 0212
console.log(num)

6、严格模式下,不容许应用 with
非严格模式下,输入 gloabl,严格模式下,间接抛出异样 Strict mode code may not include a with statement

var message = 'global'
var obj = {name: 'alice'}

with (obj) {console.log(message)
}

7、在严格模式下,eval 不再为下层援用变量
非严格模式下,eval 执行的字符串中定义变量,变量将被增加到全局,而严格模式下,不会被增加。
以下代码非严格模式下,会输入两次 global,严格模式下,输入一个 global,外加抛出异样 message is not defined

var str = "var message ='global'; console.log(message)"
eval(str)
console.log(message)

8、严格模式下,this 绑定不会默认转成对象
独立函数调用时,非严格模式下,this 指向 window,严格模式下,this 为不会默认指向 window。
以下代码在非严格模式下,输入 window 对象,严格模式下,输入 undefined

function foo(){console.log(this)
}
foo()

以上纯函数、柯里化、组合函数、with 语句、eval、严格模式都是函数式编程中的概念,对于 js 高级,还有很多须要开发者把握的中央,能够看看我写的其余博文,继续更新中~

正文完
 0