摘要:想方设法糅合过程式与函数式两种风格,忽略了闭包的基本假设,于是造出天坑。分散在各个闭包中的状态会成为的温床。当然,严格来说箭头函数也是一种闭包,因为它是函数和词法的组合。
编程语言的究极问题:过程式还是函数式?
闭包是函数式编程最先引进的,基本假设就是所有量都是常量。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
摘要:函数是一等公民。其实闭包本身也是函数式编程的一个应用。劣势不能算是严格意义上的函数式语言,很多函数式编程的特性并没有。 随着大前端时代的到来,在产品开发过程中,前端所占业务比重越来越大、交互越来越重。传统的老夫拿起JQuery就是一把梭应付当下重交互页面已经十分乏力。于是乎有了Angular,React,Vue这些现代框架。 但随之而来的还有大量的新知识新名词,如MVC,MVVM,Fl...
摘要:函数是一等公民。其实闭包本身也是函数式编程的一个应用。劣势不能算是严格意义上的函数式语言,很多函数式编程的特性并没有。 随着大前端时代的到来,在产品开发过程中,前端所占业务比重越来越大、交互越来越重。传统的老夫拿起JQuery就是一把梭应付当下重交互页面已经十分乏力。于是乎有了Angular,React,Vue这些现代框架。 但随之而来的还有大量的新知识新名词,如MVC,MVVM,Fl...
摘要:声明式编程一种编程范式,与命令式编程相对立。常见的声明式编程语言有数据库查询语言,正则表达式逻辑编程函数式编程组态管理系统等。函数式编程,特别是纯函数式编程,尝试最小化状态带来的副作用,因此被认为是声明式的。 编程范式与函数式编程 一、编程范式的分类 常见的编程范式有:函数式编程、程序编程、面向对象编程、指令式编程等。在面向对象编程的世界,程序是一系列相互作用(方法)的对象(Class...
摘要:函数式编程的定义函数是一段可以通过其名称被调用的代码。纯函数大多数函数式编程的好处来自于编写纯函数,纯函数是对给定的输入返回相同的输出的函数,并且纯函数不应依赖任何外部变量,也不应改变任何外部变量。 一个持续更新的github笔记,链接地址:Front-End-Basics,可以watch,也可以star。 此篇文章的地址:JavaScript函数式编程入门经典 正文开始 什么是函...
摘要:从某些方面来讲,这章回顾的函数知识并不是针对函数式编程者,非函数式编程者同样需要了解。什么是函数针对函数式编程,很自然而然的我会想到从函数开始。如果你计划使用函数式编程,你应该尽可能多地使用函数,而不是程序。指的是一个函数声明的形参数量。 原文地址:Functional-Light-JS 原文作者:Kyle Simpson - 《You-Dont-Know-JS》作者 关于译者:...
阅读 3076·2021-09-22 15:20
阅读 2599·2019-08-30 15:54
阅读 1965·2019-08-30 14:06
阅读 3113·2019-08-30 13:05
阅读 2456·2019-08-29 18:36
阅读 567·2019-08-29 15:10
阅读 522·2019-08-29 11:17
阅读 816·2019-08-28 18:11