引用大神的一句话:(具体是谁自己问度娘)
Shared mutable state is the root of all evil(共享的可变状态是万恶之源)
-- Pete Hunt
 
JavaScript 中的对象一般是可变的(Mutable),因为使用了引用赋值,新的对象简单的引用了原始对象,改变新的对象将影响到原始对象。
如 foo={a: 1}; bar=foo; bar.a=2 你会发现此时 foo.a 也被改成了 2
虽然这样做可以节约内存,但当应用复杂后,这就造成了非常大的隐患,Mutable 带来的优点变得得不偿失。
为了解决这个问题,一般的做法是使用 shallowCopy(浅拷贝)或 deepCopy(深拷贝)来避免被修改,但这样做造成了 CPU 和内存的浪费。
 
 

什么是 IMMUTABLE DATA

Immutable Data 就是一旦创建,就不能再被更改的数据。
对 Immutable 对象的任何修改或添加删除操作都会返回一个新的 Immutable 对象。
Immutable 实现的原理是 Persistent Data Structure(持久化数据结构),也就是使用旧数据创建新数据时,要保证旧数据同时可用且不变。
同时为了避免 deepCopy 把所有节点都复制一遍带来的性能损耗,Immutable 使用了 Structural Sharing(结构共享),即如果对象树中一个节点发生变化,只修改这个节点和受它影响的父节点,其它节点则进行共享。请看下面动画:
 
 
推荐学习ImmutableJS就应该去官网上去学习,但是自己的英语有限,虽然过了四级,但是这玩意基本上没什么卵用??
只能用一些拿来主义的东西。
ImmutableJS 提供了 7 种不可修改的资料类型:List、Map、Stack、OrderedMap、Set、OrderedSet、Record。
若是对 Immutable 物件操作都会回传一个新值。其中比较常用的有 List、Map 和 Set:
 
- Map:类似于 key/value 的 object,在 ES6 也有原生 Map 对应
 
 
const Map= Immutable.Map;

// 1. Map 大小const map1 = Map({ a: 1 });
map1.size// => 1

// 2. 新增或取代 Map 元素// set(key: K, value: V)const map2 = map1.set('a', 7);
// => Map { "a": 7 }

// 3. 删除元素// delete(key: K)const map3 = map1.delete('a');
// => Map {}

// 4. 清除 Map 内容const map4 = map1.clear();
// => Map {}

// 5. 更新 Map 元素// update(updater: (value: Map<K, V>) => Map<K, V>)// update(key: K, updater: (value: V) => V)// update(key: K, notSetValue: V, updater: (value: V) => V)const map5 = map1.update('a', () => (7))
// => Map { "a": 7 }

// 6. 合并 Map const map6 = Map({ b: 3 });
map1.merge(map6);
// => Map { "a": 1, "b": 3 }

 
- List:有序且可以重复值,对应于一般的 Array
 
const List= Immutable.List;

// 1. 取得 List 长度const arr1 = List([1, 2, 3]);
arr1.size// => 3

// 2. 新增或取代 List 元素内容// set(index: number, value: T)// 将 index 位置的元素替换const arr2 = arr1.set(-1, 7);
// => [1, 2, 7]const arr3 = arr1.set(4, 0);
// => [1, 2, 3, undefined, 0]

// 3. 删除 List 元素// delete(index: number)// 删除 index 位置的元素const arr4 = arr1.delete(1);
// => [1, 3]

// 4. 插入元素到 List// insert(index: number, value: T)// 在 index 位置插入 valueconst arr5 = arr1.insert(1, 2);
// => [1, 2, 2, 3]

// 5. 清空 List// clear()const arr6 = arr1.clear();
// => []

 
- Set:没有顺序且不能重复的列表
 
const Set= Immutable.Set;

// 1. 建立 Setconst set1 = Set([1, 2, 3]);
// => Set { 1, 2, 3 }

// 2. 新增元素const set2 = set1.add(1).add(5);
// => Set { 1, 2, 3, 5 } // 由于 Set 为不能重复集合,故 1 只能出现一次

// 3. 删除元素const set3 = set1.delete(3);
// => Set { 1, 2 }

// 4. 取联集const set4 = Set([2, 3, 4, 5, 6]);
set1.union(set4);
// => Set { 1, 2, 3, 4, 5, 6 }

// 5. 取交集set1.intersect(set4);
// => Set { 2, 3 }

// 6. 取差集set1.subtract(set4);
// => Set { 1 }

 
 
看到这里,你已经基本上掌握了,他的基本的API。但是这玩意写代码的时候说不定就冒出什么你不认识的API,
举个栗子:
const  map=Immutable.map();

//...........

map.getIn()

  immutableData.getIn(['a', 'b']) // {a:{b:2}} 得到2。访问深层次的key

看到了吧,你还是不会的,加油学习吧

 
 
ImmutableJS 的特性整理
 
// 有些开发者在使用时会在 ``Immutable` 变数前加 `$` 以示区隔。

const $obj = fromJS({
a: 1
});

funcationA($obj);
console.log($obj.get('a')) // 1

 
  1. Structural Sharing 为了维持资料的不可变,又要避免像 deepCopy 一样复制所有的节点资料而造成的资源损耗,在 ImmutableJS 使用的是 Structural Sharing 特性,亦即如果物件树中一个节点发生变化的话,只会修改这个节点和和受它影响的父节点,其他节点则共享。
const obj = {
  count: 1,
  list: [1, 2, 3, 4, 5]
}
var map1 = Immutable.fromJS(obj);
var map2 = map1.set('count', 4);

console.log(map1.list === map2.list); // true

 
  1. Support Lazy Operation
Immutable.Range(1, Infinity)
.map(n => -n)
// Error: Cannot perform this action with an infinite size.

Immutable.Range(1, Infinity)
.map(n => -n)
.take(2)
.reduce((r, n) => r + n, 0);
// -3

 
4.丰富的 API 并提供快速转换原生 JavaScript 的方式 在 ImmutableJS 中可以使用 fromJS()toJS() 进行 JavaScript 和 ImmutableJS 之间的转换。但由于在转换之间会非常耗费资源,所以若是你决定引入 ImmutableJS 的话请尽量维持资料处在 Immutable 的状态。
 
 
5.支持 Functional Programming Immutable 本身就是 Functional Programming(函数式程式设计)的概念,所以在 ImmutableJS 中可以使用许多 Functional Programming 的方法,例如:mapfiltergroupByreducefindfindIndex 等。
 

React 效能优化

ImmutableJS 除了可以和 Flux/Redux 整合外,也可以用于基本 react 效能优化。以下是一般使用效能优化的简单方式:

传统 JavaScript 比较方式,若资料型态为 Primitive 就不会有问题:

// 在 shouldComponentUpdate 比较接下来的 props 是否一致,若相同则不重新渲染,提升效能shouldComponentUpdate (nextProps) {
return this.props.value !== nextProps.value;
}

但当比较的是物件的话就会出现问题:

// 假设 this.props.value 为 { foo: 'app' }// 假设 nextProps.value 为 { foo: 'app' },// 虽然两者值是一样,但由于 reference 位置不同,所以视为不同。但由于值一样应该要避免重复渲染this.props.value !== nextProps.value; // true
使用 ImmutableJS
 
 
var SomeRecord = Immutable.Record({ foo: null });
var x = new SomeRecord({ foo: 'app'  });
var y = x.set('foo', 'azz');
x === y; // false
 
在 ES6 中可以使用官方文件上的 PureRenderMixin 进行比较,可以让程式码更简洁:
 
import PureRenderMixin from 'react-addons-pure-render-mixin';
class FooComponent extends React.Component {
  constructor(props) {
    super(props);
    this.shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate.bind(this);
  }
  render() {
    return <div className={this.props.className}>foo</div>;
  }
}

 
 
 
 
 
 
 
 
 
 
 
 

原生js转换为immutableData

Immutable.fromJS([1,2]) // immutable的 list

Immutable.fromJS({a: 1}) // immutable的 map

从immutableData 回到 JavaScript 对象

immutableData.toJS()

判断两个immutable数据是否一致

Immutable.is(immutableA, immutableB)

判断是不是map或List

Immutable.Map.isMap(x)

Immutable.Map.isList(x)

对象合并(注意是同个类型)

immutableMaB = immutableMapA.merge(immutableMaC)

Map的增删查改

immutableData.get('a') // {a:1} 得到1。

immutableData.getIn(['a', 'b']) // {a:{b:2}} 得到2。访问深层次的key

增和改(注意不会改变原来的值,返回新的值)

immutableData.set('a', 2) // {a:1} 得到1。

immutableData.setIn(['a', 'b'], 3)

immutableData.update('a',function(x){return x+1})

immutableData.updateIn(['a', 'b'],function(x){return x+1})

immutableData.delete('a')

immutableData.deleteIn(['a', 'b'])

List的增删查改

如同Map,不过参数变为数字索引。

比如immutableList.set(1, 2)

其它便捷函数

如同underscore的方法,都有噢。

ImmutableJS的更多相关文章

  1. immutableJS一些API

    原生js转换为immutableData Immutable.fromJS([1,2]) // immutable的 list Immutable.fromJS({a: 1}) // immutabl ...

  2. redux、immutablejs和mobx性能对比(一)

    一.前言 关于react的性能优化,有很多方面可以去做,而其中避免重复渲染又是比较重要的一点,那么为什么react会重复渲染,我们又该如何避免重复渲染呢,关于这方面官方其实早有说明:避免重复渲染,这里 ...

  3. redux、immutablejs和mobx性能对比(三)

    四.我的结论 通过第三部分的数据数据分析,我觉得我们可以得到以下结论: 无论是在开发环境还是测试环下页面的首次加载速度结果都是:redux>immutablejs>mobx,但是他们之间的 ...

  4. redux、immutablejs和mobx性能对比(二)

    三.分析数据 1.前提说明 我对测试出的10个数据摘除最大值与最小值,然后求平均值 根据平均值我绘制了一个曲线图一个柱状图 曲线图用于查看1000-100000的性能趋势 柱状图用于比较在相同条数下r ...

  5. immutable-js基础

    Immutable.js(和原生方法不同): 用于深层次的数组和对象的比较   数据结构:Map Set Seq List Rang(和原生不同)   首先:先忘记es5 es6的数组对象方法   官 ...

  6. [Immutable.js] Updating nested values with ImmutableJS

    The key to being productive with Immutable JS is understanding how to update values that are nested. ...

  7. 最新Angular2案例rebirth开源

    在过去的几年时间里,Angular1.x显然是非常成功的.但由于最初的架构设计和Web标准的快速发展,逐渐的显现出它的滞后和不适应.这些问题包括性能瓶颈.滞后于极速发展的Web标准.移动化多平台应用, ...

  8. JavaScript资源大全中文版(Awesome最新版)

    Awesome系列的JavaScript资源整理.awesome-javascript是sorrycc发起维护的 JS 资源列表,内容包括:包管理器.加载器.测试框架.运行器.QA.MVC框架和库.模 ...

  9. React 组件性能优化

    React组件性能优化 前言 众所周知,浏览器的重绘和重排版(reflows & repaints)(DOM操作都会引起)才是导致网页性能问题的关键.而React虚拟DOM的目的就是为了减少浏 ...

随机推荐

  1. 手动脱RLPack壳实战

    作者:Fly2015 吾爱破解论坛培训第一课选修作业练习的第7题. 这个壳没听说过.可是脱起来比較简单.依据ESP定律就可以直达光明,Dump出原来的程序. 老规矩.首先对须要脱壳的程序进行查壳处理. ...

  2. netty4与protocol buffer结合简易教程

    各项目之间通常使用二进制进行通讯,占用带宽小.处理速度快~ 感谢netty作者Trustin Lee.让netty天生支持protocol buffer. 本实例使用netty4+protobuf-2 ...

  3. 【code】flex_进度条样式

    近期打算吧硬盘中的资料记录在博客中,实用的就当是个分享,无用的就当是个备份,还望大家不要见怪. 一共4个文件: JinDuTiaoItem.mxml: <?xml version="1 ...

  4. [Qt总结篇]终端远程升级client

    环境: QT4.8.5 for Windows(Qt Creator+MinGW) 一.写在前面: 1.深度:鉴于C/C++的功底还远远不足,个人主要精力还是学习C/C++,所以没打算继续深入研究Qt ...

  5. java并发编程之Semaphore

    信号量(Semaphore).有时被称为信号灯.是在多线程环境下使用的一种设施, 它负责协调各个线程, 以保证它们可以正确.合理的使用公共资源. 一个计数信号量.从概念上讲,信号量维护了一个许可集.如 ...

  6. JSON-JSON字符串转换成JSON对象、JSON对象数组、java实体类以及保存到List列表中

    处理JSON字符串时,一直出错,写个样例后发现原来是没有弄清楚数据的格式问题. 实现的是 JSONString 转换成java对象 或是 list列表 实例类 News package lyx.ent ...

  7. SpringMVC 运行过程

    加入jar包 在web.xml中配置DispatherServlet 加入SpringMVC配置文件 编写处理请求的处理器,并表示为处理器 编写视图 可见的运行流程: 实际的运行流程:

  8. HDU2072单词数

    #include<iostream> #include<set> #include<sstream> using namespace std; int main() ...

  9. socket listen backlog

    http://stackoverflow.com/questions/4253454/question-about-listening-and-backlog-for-sockets The list ...

  10. HDU 1517:A Multiplication Game

    A Multiplication Game Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Ot ...