在JS中实践函数式编程【3】 -- 状态

883 阅读4分钟

写在文章前

函数式编程第三话~ 上次介绍了一些简单的概念,这次我们研究一下状态。

文章如果有什么不对的地方欢迎在评论区批评指正。

状态

上次说到什么是一等函数 什么是高阶函数以及纯函数。那接下来我们来研究一下函数式编程中 ,纯函数到底是如何帮助我们的。

首先我们要知道一个词: 状态。 前端的小伙伴一定对状态这个词不陌生,在vue 和react 中都有强大的状态管理器做支撑。那到底什么是状态呢?

简单的理解就是当前关于事物的一个描述。人的状态就是一个人当前样子的描述。程序的状态就是程序当前各个组成部分的状态:比如变量当前的值,比如已经分配了的线程的情况等等。。其实应用程序的状态就是当前正在发生信息的汇总。这么说有点抽象,我们来举个例子:

let userInfo = {
    accountNo: 'No000001',
    id: 1,
    name: 'john smith'
};
let readingBooks = 0;
let owningBooks = 0;

owningBooks = owningBooks + 1;
readingBooks = readingBooks + 1;

let buyBooksFromDangDang = (hasCheckout) => {
    let booksAmount = 3;
    if (hasCheckout) {
        owningBooks = owningBooks + booksAmount;
    }
    return booksAmount;
}


代码中我们看到修改全局状态的情况,如果是全局状态(userInfo,readingBooks)的话,在任何地方任何代码都可以修改这些变量的值。但如果是在函数作用域中我们声明的局部变量(booksAmount)的话,在函数的外部是没有办法访问这些局部变量的。并且在每一次我们去执行buyBooksFromDangDang的时候,变量booksAmount 都会被创建一次,并且初始化赋值为3。

对于一个应用程序来说,他的状态不仅仅只是他的全局变量,还有他的每一个组件内部私有的值等等。每个组件内部的函数,函数内部的变量,函数内部的函数,函数内部的函数的变量(递归下去)等等。

共享状态

共享状态的好处就是任何地方都能访问这些变量,共享状态的缺点也是任何地方都能访问这些变量。js又是一个单线程的语言,我们也没有锁的机制,所以所有关于共享变量的控制都是由我们自己来完成的。这就很可能会造成不知道什么时候,改变了这个变量就导致了一些错误,这些错误如果是在一个复杂的程序中会变得难以定位,因为谁(任何函数)都有权限去更改。所以使用共享状态的时候要慎重,共享给的代码块越多越要慎重。

那怎么办,我如果有变量要共享怎么办?

参数

let buyBooksFromDangDang = (hasCheckout) => {
    let booksAmount = 3;
    if (hasCheckout) {
        booksAmoiunt = owningBooks + booksAmount;
    }
    return booksAmount;
}

首先,在说参数之前,我们先来思考一下,这些我们需要共享的变量他们真的有必要被共享吗? 就拿上面的代码块来说,在buyBooksFromDangDang中我们引用了全局变量owningBooks. 那如果owningBooks更改了的话,booksAmount的结果也会跟着改变。那怎样才能让我们的结果保证可控呢?

let buyBooksFromDangDang = (hasCheckout, owningBooks) => {
    let booksAmount = 3;
    if (hasCheckout) {
        booksAmoiunt = owningBooks + booksAmount;
    }
    return booksAmount;
}

我们可以将owningBooks 作为参数传入函数,这样就不会有那种“在执行的时候,我们不知道值是什么”的情况。

但要注意,我们需要保证传入参数的不可变性。举个非常常见的例子,我们如果传入了一个对象,然后对某个属性做了更改,或者我们做了浅拷贝然后做了更改。。。这时的对象就已经不是我们初次相识的样子了,对象的值已经不可控了。

函数式编程要求我们总要返回全新的对象,并且不会对传入的参数进行任何的改变。当然对于一些必要的使用全局变量的情况,还是别勉强自己了,做个愉快CRUD Boy吧:)

总结

这次介绍了状态的一些知识点,以及公共变量的一些问题,但其实我们没有很仔细的说明到底公共变量与我们之前提的纯函数以及函数式编程的具体关系。接下来,我们会具体的讲一下他们之间的关系。

【PS】公司依旧还在招聘,需要内推的小伙伴欢迎私戳。