JavaScript 函数式编程读书笔记2
概述
这是我读《javascript函数式编程》的读书笔记,供以后开发时参考,相信对其他人也有用。
说明:虽然本书是基于underscore.js库写的,但是其中的理念和思考方式都讲的很好,值得一读。不过如果不熟悉underscore.js库的话,读起来会有点困难。
对象的不变性
函数式编程中函数是一等公民,所以对于数据来说,需要他们是不可变的。另外,对象的不可变确实能够带来一些好处,比如:如果数据是不可变的,那么可以直接通过“===”来判断数据是否发生变化,这使得react的效率得到极大提升。下面我们来讨论在js中实现immutable对象的方法。
freeze
用Object.freeze可以冻结一个数组或者对象,当使用Object.freeze的时候,将导致后续的变化失败。如果在严格模式下使用,将抛出一个TypeError;否则,所有的变化将悄悄地失败。实例如下:
var a = [2,3,4];
a[1]; //输出3
Object.freeze(a);
a[1]=5;
a[1]; //输出3
也有一个isFrozen API来判断a是否确实被冻结。
Object.isFrozen(a); //输出true
但是这么实现有如下几个痛点:
- 变化会悄悄地失败,可能会导致微妙的错误。
- 不是所有的库都支持freeze。
- 这个是最重要的,Object.freeze是一个浅操作。
由于Object.freeze是一个浅操作,所以嵌套对象里面的变量不会被冻结,除非用递归进行深冻结,代码如下:
function isObject(obj) {
var type = typeof obj;
return type === 'function' || type === 'object' && !!obj;
}
function deepFreeze(obj) {
if(!Object.isFrozen(obj)) Object.freeze(obj);
for (var key in obj) {
if(!obj.hasOwnProperty(key) || !isObject(obj)) continue;
deepFreeze(obj[key]);
}
}
使用容器
我们也可以使用深复制,并把它放在一个容器里面来保持变量的不变性。简单代码如下:
function isObject(obj) {
var type = typeof obj;
return type === 'function' || type === 'object' && !!obj;
}
function deepClone(obj) {
if(!isObject(obj)) return obj;
var temp = new obj.constructor();
for (var key in obj) {
if(obj.hasOwnProperty(key))
temp[key] = deepClone(obj[key]);
}
return temp;
}
function Container(init) {
this.state = init;
}
Container.prototype = {
setState: function(obj) {
this.state = deepClone(obj);
return this.state;
}
}
var aObj = new Container({a:{b:1}, c:2});
aObj.setState({a:{b:3}, c:6, d:8});
aObj; //输出{a:{b:3}, c:6, d:8}
使用immutable.js
使用上面的方法实现不可变数据问题很多,用freeze会悄悄地失败,并且是浅操作,使用容器的话深复制对象会消耗大量的内存,并且速度很慢。
immutable.js就是facebook开源的为了解决这个问题的库。它可以说是和react一样的划时代的产物。它通过参考hash maps tries和hash maps tries提供了一种优雅地实现javascript Immutable Data的方式。
它使用了Structural Sharing(结构共享),即如果对象树中一个节点发生变化,只修改这个节点和受它影响的父节点,其它节点则进行共享。所以避免了深拷贝带来的CPU 和内存的浪费。
具体可参考:
搞定immutable.js详细说明
IMMUTABLE 详解
JavaScript 函数式编程读书笔记2的更多相关文章
- JavaScript 函数式编程读书笔记1
概述 这是我读<javascript函数式编程>的读书笔记,供以后开发时参考,相信对其他人也有用. 说明:虽然本书是基于underscore.js库写的,但是其中的理念和思考方式都讲的很好 ...
- Node.js高级编程读书笔记Outline
Motivation 世俗一把,看看前端的JavaScript究竟能做什么. 顺便检验一下自己的学习能力. Audience 想看偏后台的Java程序员关于前端JavaScript的认识的职业前端工程 ...
- 转:JavaScript函数式编程(三)
转:JavaScript函数式编程(三) 作者: Stark伟 这是完结篇了. 在第二篇文章里,我们介绍了 Maybe.Either.IO 等几种常见的 Functor,或许很多看完第二篇文章的人都会 ...
- 转: JavaScript函数式编程(二)
转: JavaScript函数式编程(二) 作者: Stark伟 上一篇文章里我们提到了纯函数的概念,所谓的纯函数就是,对于相同的输入,永远会得到相同的输出,而且没有任何可观察的副作用,也不依赖外部环 ...
- 转:JavaScript函数式编程(一)
转:JavaScript函数式编程(一) 一.引言 说到函数式编程,大家可能第一印象都是学院派的那些晦涩难懂的代码,充满了一大堆抽象的不知所云的符号,似乎只有大学里的计算机教授才会使用这些东西.在曾经 ...
- python高级编程读书笔记(一)
python高级编程读书笔记(一) python 高级编程读书笔记,记录一下基础和高级用法 python2和python3兼容处理 使用sys模块使程序python2和python3兼容 import ...
- C++Windows核心编程读书笔记
转自:http://www.makaidong.com/%E5%8D%9A%E5%AE%A2%E5%9B%AD%E6%96%87/71405.shtml "C++Windows核心编程读书笔 ...
- 一文带你了解JavaScript函数式编程
摘要: 函数式编程入门. 作者:浪里行舟 Fundebug经授权转载,版权归原作者所有. 前言 函数式编程在前端已经成为了一个非常热门的话题.在最近几年里,我们看到非常多的应用程序代码库里大量使用着函 ...
- javascript函数式编程和链式优化
1.函数式编程理解 函数式编程可以理解为,以函数作为主要载体的编程方式,用函数去拆解.抽象一般的表达式 与命令式相比,这样做的好处在哪?主要有以下几点: (1)语义更加清晰 (2)可复用性更高 (3) ...
随机推荐
- jmeter 实现 mysql 存储过程
Callable Statement:存储过程语句.可以在一个脚本里实现增删改查. 实现方法: 1)首先创建一个存储过程 2)然后执行这个存储过程
- matlab中变量问题——readonly 索引超出矩阵维度 workspacefunc 215
matlab程序运行过程中会出现如上提示,在网上检索未果,键入dbstop if error语句也无法定错误之处,就想这个错误不是一般的错误. 通过间隔打断点的方式最后定位错误为一句exist = f ...
- 搭建mxnet-gpu docker的pyhon remote kernel
起因 最近看mxnet的东西,打算给实验室的机器装一个mxnet的环境,无奈实验室里面机器已经装了tensorflow,运行了好久了,环境比较老.而mxnet可是支持最新的cuda9.1和cudnn7 ...
- prim及其练习
关于prim,其实我今天才学... prim其实就是最小生成树的一种算法,严格每次的找最小边连到树上.看书上的代码看不懂,于是就自己大胆用堆优化写prim. 搞了很长时间,经过不写努力,还是搞出来了. ...
- spark streaming之三 rdd,job的动态生成以及动态调度
前面一篇讲到了,DAG静态模板的生成.那么spark streaming会在每一个batch时间一到,就会根据DAG所形成的逻辑以及物理依赖链(dependencies)动态生成RDD以及由这些RDD ...
- 【VBA】セールの最初起動時、VBAを自動的に実行方法
方法一 セールの「ThisWorkbook」にて.「Workbook」の「Open」関数にて.ロジックを追加する Private Sub Workbook_Open() Msgbox "He ...
- 《java并发编程实战》笔记
<java并发编程实战>这本书配合并发编程网中的并发系列文章一起看,效果会好很多. 并发系列的文章链接为: Java并发性和多线程介绍目录 建议: <java并发编程实战>第 ...
- 第一章 C++语言入门
标准数据类型 C++语言提供了丰富的数据类型,如整数类型.实数类型(浮点数).字符类型等.每种数据类型均有均值范围,Dev-C++(4.9.9.2)是Windows平台 ...
- python积累二:中文乱码解决方法
根据网上提供的解决方法:添加#coding=utf-8或# -*- coding: utf-8 -*- #coding=utf-8 print "还不行?" 执行结果:还是乱码!: ...
- 在IIS7里配置 ISAPI,运行dll程序,总提示下载dll
在IIS7里配置 ISAPI,运行dll程序,总提示下载dll,只需要把对应站点应用程序池里面的高级设置里的启用32位应用程序,设为“true"即可.