0
点赞
收藏
分享

微信扫一扫

了解 JavaScript 函数式编程

函数式编(Function Programming, FP) 是编程范式之一。

编程范式即编程规范,编程风格

我们常听听说的编程范式还有:

  • 面向对象:典型的就是​​java​​​ 语言,目前​​javascript​​​ 的超集​​typescript​​ 也是走这条路线。也就是把事物抽象成程序世界中的类和对象,通过封装、继承和多态来演示事物之间的联系。
  • 面向过程:典型的就是​​C​​ 语言。在面向过程程序设计中,问题被看成是一些列需要完成的任务,函数则用于完成这些任务,可以看成一步步升级打怪。

而我们今天要讨论的编程范式 -- 函数式编程把事物和事物直接的联系抽象到程序世界,强调的是函数的计算,对运算过程进行抽象。使用函数进行编程

纯函数

纯函数 指相同的输入永远得到相同的输出,而且没有副作用。

如下: ​​slice​​​ 是纯函数,​​splice​​ 就不是。

let arr = [1, 2, 3];
console.log(arr.slice(0,1)); // 1
console.log(arr.slice(0,1)); // 1
console.log(arr.slice(0,1)); // 1

let another_arr = [3, 4, 5];
console.log(another_arr.splice(0,1)); // 3
console.log(another_arr.splice(0,1)); // 4
console.log(another_arr.splice(0,1)); // 5

纯函数是函数编程的重点。函数是函数编程的一等公民。

一等公民,指函数跟其他类型具有相同的地位,也就是说 ​​function​​​ 可以当作令一个 ​​function​​​ 的参数,也可以作为 ​​function​​ 的返回值,也可以作为变量。

比如:

function demo(cb) {
cb()
}

function add(x) {
return function(y) {
return x + y
}
}

const val = () => 'jimmy';

声明式编程

函数式编程属于声明式编程范式。

声明式编程范式:会描述一些列的操作,但是并不会暴露他们是如何实现的或者数据流是如何传递的。

比如:

let arr = ['hello', 'world', '!']
// 命令式,暴露具体实现
for(let i = 0; i < arr.length; i++) {
arr[i] = arr[i].toUpperCase()
}

// 声明式,隐藏细节
arr.map(str => str.toUpperCase()

引用透明

引用透明(Referential Transparency)指的是一个函数穿传入相同的参数,不管运算多少次,永远会得到相同的值,并且不对外部世界产生任何改变(上面我们已经提到过,就是不产生副作用)。

例子可以参考上面纯函数的例子。

又比如:

function change_style() {
let dom = document.getElementById('demo');
dom.style.color = 'red';
}
// change_style 对外界产生的副作用,更改了 dom 的样式

不可变性

不可变性,就是数据一旦创建后就不会再改变的,所有对不可变性的数据操作返回的是另一个不可变性的数据。这好比操作 ​​const​​ 定义变量一样。

又比如:

let obj = {
name: 'jimmy'
}
let person = obj;
person.name = 'Jimmy';
console.log(obj.name); // Jimmy
// 此时,对象 obj.name 数据已经发生了改变(可变)

let obj1 = {
name: 'jimmy'
}
let person1 = { ...obj, name: 'Jimmy'};
console.log(obj1.name); // jimmy
// 此时,对象 obj.name 数据没发生变化(不可变)

好了,我们来总结下函数式编程应该具有的特征:

  • 纯函数
  • 函数是一等公民
  • 声明式编程
  • 引用透明
  • 不可变性

以下面的节流函数应用结束本文:

function throttle(fn) {
let canRun = true;
return function() {
if(!canRun) {
return;
}
canRun = false;
setTimeout(() => {
fn.call(this, arguments);
canRun = true;
}, 1000)
}
}

【完】✅

举报

相关推荐

0 条评论