资讯专栏INFORMATION COLUMN

Javascript闭包:从过程式到函数式

leone / 1506人阅读

摘要:想方设法糅合过程式与函数式两种风格,忽略了闭包的基本假设,于是造出天坑。分散在各个闭包中的状态会成为的温床。当然,严格来说箭头函数也是一种闭包,因为它是函数和词法的组合。

编程语言的究极问题:过程式还是函数式?

闭包是函数式编程最先引进的,基本假设就是所有量都是常量。Javascript想方设法糅合过程式与函数式两种风格,忽略了闭包的基本假设,于是造出天坑。

是什么

闭包的定义是“函数和声明该函数的词法环境的组合” MDN,换言之,就是带着环境(上下文、状态、属性、局部变量,找一个你能理解的词)的函数。从ES2015起,最简单的闭包变成了这样:

{
  let localVar = 1;
  whatever.onclick = () => localVar++;
}

whatever.onclick就是一个闭包,因为它带着localVar

从这个角度上来说,所有Javascript函数都是闭包,因为他们都能访问到window下面的全局变量,如果传递给另一个框架的话,用的都是自带的全局变量环境。

为什么

上面的闭包非常糟糕,糟糕就在于它不是纯函数它是有状态的。分散在各个闭包中的状态会成为bug的温床。以foo为例,每次调用都会有副作用,得到的值都不一样,状态在哪里又找不着(假设你忘了localVar是啥),给debug造成极大的困难。

现在主流的状态管理框架Flux/Redux/Vuex的思想全都是集中状态管理。还把状态分散到一个一个闭包里面,是过时的。

那我们把状态保存在哪里?this里。

虽然this也是JS的一个天坑,但是比起闭包来,简直好太多了。this最伟大的功勋就在于函数和环境的解耦(跟闭包正好相反)。

let bar = function() { this.a++ }
let state = { a: 1, bar };

这个时候有同学就要问了,state.bar()还是有副作用的呀,得到的值还是不一样,好处在哪?好处在于

bar前面是什么?是一个对象state,我们现在能确定bar的副作用在哪里了;

bar本身没有副作用,只要我们深拷贝state,我们就能历史回放state.bar()是怎么出bug的。

以上两点简直是debug的福音。

怎么办

能减少bug,又实际的写法:

只有对象保存状态,不论是字面量,还是new。函数可以读状态,写状态必须用this.xxx或者用参数把对象传进来。

为什么说2018(其实2015+就行了)年就可以少用闭包了呢?

因为我们有class关键字了,以前创建用得上this的类实在是太麻烦了;

因为我们有箭头函数了,用闭包保存this的做法也不必要了。

当然,严格来说箭头函数也是一种闭包,因为它是函数和词法this的组合。但是this能保证只读,函数并不能用this写状态,因此仍然满足上面说的两个好处。

所以直接说箭头函数就是闭包,我天天用,秀面试官一脸就行了,他不懂的话就潇洒离去,这破地方配不上你 :)

所以,React强推class,Vue用的也是this,都用对象存状态。既然状态都被对象存了,自然也就没闭包什么事了。

我的相关文章

Javascript闭包:从理论到实现,[[Scopes]]的每一根毛都看得清清楚楚

以上所有代码按Mozilla Public License, v. 2.0授权。
以上所有文字内容按CC BY-NC-ND 4.0授权。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/95482.html

相关文章

  • JavaScript 函数编程底是个啥

    摘要:函数是一等公民。其实闭包本身也是函数式编程的一个应用。劣势不能算是严格意义上的函数式语言,很多函数式编程的特性并没有。 随着大前端时代的到来,在产品开发过程中,前端所占业务比重越来越大、交互越来越重。传统的老夫拿起JQuery就是一把梭应付当下重交互页面已经十分乏力。于是乎有了Angular,React,Vue这些现代框架。 但随之而来的还有大量的新知识新名词,如MVC,MVVM,Fl...

    denson 评论0 收藏0
  • JavaScript 函数编程底是个啥

    摘要:函数是一等公民。其实闭包本身也是函数式编程的一个应用。劣势不能算是严格意义上的函数式语言,很多函数式编程的特性并没有。 随着大前端时代的到来,在产品开发过程中,前端所占业务比重越来越大、交互越来越重。传统的老夫拿起JQuery就是一把梭应付当下重交互页面已经十分乏力。于是乎有了Angular,React,Vue这些现代框架。 但随之而来的还有大量的新知识新名词,如MVC,MVVM,Fl...

    Aomine 评论0 收藏0
  • 编程范函数编程

    摘要:声明式编程一种编程范式,与命令式编程相对立。常见的声明式编程语言有数据库查询语言,正则表达式逻辑编程函数式编程组态管理系统等。函数式编程,特别是纯函数式编程,尝试最小化状态带来的副作用,因此被认为是声明式的。 编程范式与函数式编程 一、编程范式的分类 常见的编程范式有:函数式编程、程序编程、面向对象编程、指令式编程等。在面向对象编程的世界,程序是一系列相互作用(方法)的对象(Class...

    noONE 评论0 收藏0
  • JavaScript函数编程入门经典

    摘要:函数式编程的定义函数是一段可以通过其名称被调用的代码。纯函数大多数函数式编程的好处来自于编写纯函数,纯函数是对给定的输入返回相同的输出的函数,并且纯函数不应依赖任何外部变量,也不应改变任何外部变量。 一个持续更新的github笔记,链接地址:Front-End-Basics,可以watch,也可以star。 此篇文章的地址:JavaScript函数式编程入门经典 正文开始 什么是函...

    silvertheo 评论0 收藏0
  • 翻译连载 |《你不知道的JS》姊妹篇 |《JavaScript 轻量级函数编程》- 第 2 章:函

    摘要:从某些方面来讲,这章回顾的函数知识并不是针对函数式编程者,非函数式编程者同样需要了解。什么是函数针对函数式编程,很自然而然的我会想到从函数开始。如果你计划使用函数式编程,你应该尽可能多地使用函数,而不是程序。指的是一个函数声明的形参数量。 原文地址:Functional-Light-JS 原文作者:Kyle Simpson - 《You-Dont-Know-JS》作者 关于译者:...

    Riddler 评论0 收藏0

发表评论

0条评论

leone

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<