immutable学习

immutable学习

简介

js 中的对象时引用赋值,是可变的,新的对象简单的引用原始的对象,改变新的对象将影响到原始对象,这样虽然可以节约内存,但是当应用复杂后,会造成很大的隐患,一般的解决办法是进行浅拷贝和深拷贝来避免被修改,但是这样会造成内存的浪费,引用自Immutable 详解及 React 中实践

Immutable Data 就是一旦创建,就不能再被更改的数据。对其进行任何修改和删除操作都会返回一个新的对象,Immutable 使用了结构共享:如果对象树中的 一个节点发生变化,只修改这个节点和受它影响的父节点,其他节点则进行共享

Immutable API

is()

比较两个对象或数组的值是否相等,只要值相等就返回true,(只能比较 Map List类型的数据)

    let arr = [1,2,3,4];
    let $arr = List(arr);
    let $arr2 = List(arr);
    let arr3 = List(arr).toJS();
    console.log($arr);
    console.log($arr === $arr2); // false
    console.log(Immutable.is($arr, $arr2)); // true
    console.log(Immutable.is(arr3, $arr2)); // false 非 Map List类型比较返回false
类型转换
fromJS()

将普通的js Object 和 Array,深度的转换为不可变的 Map 和 List

toJS() toJSON()

深度转换成等值的js

    let a = Immutable.fromJS([{a:111,b:222}, [3, 4, 5, 6]])
    let b = a.toJS(); 
    let c = a.toJSON(); 

    console.log(b); // [{a:111,b:222}, [3, 4, 5, 6]]
    console.log(c); // [{a:111,b:222}, [3, 4, 5, 6]]
toList() toMap()

浅度转换为 List Map

    let a = Map({1:[1,[2,3,4],{a:11,b:22}],2:[222,333]});
    let b = a.toList();
    let c = b.toMap();
    console.log(a.toJS()); // Object {1: Array[3], 2: Array[2]}
    console.log(b.toJS()); // [Array[3], Array[2]]
    console.log(c.toJS()); // Object {0: Array[3], 1: Array[2]}
toArray() toObject()

浅度转换成js数组或者对象,(不是给原生数组和对象使用的,原生js没有这些方法,会报错)

    let a = Immutable.fromJS([{a:111,b:222}, [3, 4, 5, 6]])
    let b = Immutable.fromJS({1 :{a:111,b:222},2: [3, 4, 5, 6]})
    let c = a.toArray(); 
    let d = b.toObject(); 
    console.log(a); // List [Map, List]
    console.log(b); // Map {1 : Map, 2 : List}
    console.log(c); // [Map, List]
    console.log(d); // {1 : Map, 2 : List}
List() Map()

列表,地图 ,不可变的

List.isList()

判断提供的值,是否是 List 类型数据

    let arr = [1,2,3,4];
    let $arr = List(arr);
    console.log(List.isList(arr));  // false
    console.log(List.isList($arr)); // true
List.of()

根据传入的值,创建一个列表

    let $arr1 = List.of(1,2,3,6);
    let $arr2 = List.of({a:999},8,[2,3,4]);
    console.log($arr1.toJS());  // [1, 2, 3, 6]
    console.log($arr2.toJS()); // [{a:999},8,[2,3,4]]
Map.isMap()

判断是否是 Map 类型

Map.of()

创建 Map

    let $obj = Map.of('aa','bb','22','cc','33','11');
    console.log('obj =' + $obj); // obj =Map { "aa": "bb", "22": "cc", "33": "11" }
.size

返回 对应类型数据的长度

    let $arr1 = List.of(1,2,3,6);
    let $arr2 = List.of({a:999},8,[2,3,4]);
    console.log($arr1.size);  // 4
    console.log($arr2.size); // 3
.set(key, value)

根据传入的新的数据,返回一个新的 对应类型数据

  • 如果key已经存在,旧的value会被替换
  • List负数key 表示从 List 末尾开始计数
  • index 大于 List 的 size 则 返回的 List 的 size 会包含 index
    let $arr = List.of(1,2,3,6);
    let $arr2 = $arr.set(9,222); // 表示第10(索引从0开始)位是222
    let $arr3 = $arr.set(-1,999);
    let $arr4 = $arr.set(-7,777);
    console.log($arr.toJS());  // [1, 2, 3, 6] size : 4
    console.log($arr2.toJS()); 
    // [1, 2, 3, 6, undefined, undefined, undefined, undefined, undefined, 222] size : 10
    console.log($arr3.toJS()); // [1, 2, 3, 999]
    console.log($arr4.toJS()); // [777, undefined, undefined, 1, 2, 3, 6] size : 7
    let a = Map({a:1, b:2, c:3});
    let b = a.set('b',77);
    let c = a.set('d',99);
    console.log('b = ' + b); // b = Map { "a": 1, "b": 77, "c": 3 }
    console.log('c = ' + c); // c = Map { "a": 1, "b": 2, "c": 3, "d": 99 }
.get(key)

返回根据key 对应的值

    let $arr = List([1,2,3,List([11,22]),5]);
    let str = $arr.get(2);
    console.log($arr);
    console.log(str); // 3
    let map = Map({1:'one'});
    console.log(map.get(1)); // undefined
    console.log(map.get('1')); // one
.has(key)

判断是否存在 key 对应的 键(不是值),(只在第一层中查找)

    let $arr = List([1,2,3,List([11,22]),5]);
    let bl = $arr.has(3);
    let bln = $arr.has(11);
    console.log($arr);
    console.log(bl); // true
    console.log(bln); // false
.includes(value)

判断 是否存在 value 对应的值,(只在第一层中查找)

    let $arr = List([1,[11,22,33,44],3]);
    let bl = $arr.includes(3);
    let bl2 = $arr.has(3);
    let bln = $arr.includes(11);
    console.log(bl); // true
    console.log(bl2); // false
    console.log(bln); // false
.first() .last()

返回第一个、最后一个值

    let $arr = List([1,[11,22,33,44],3]);
    let fir = $arr.first();
    let las = $arr.last();
    console.log(fir); // 1
    console.log(las); // 3
.delete(key)

返回一个新的 List或者Map 不包括这个key 对应的值 ,(List 中 index 负数 ,表示从末尾开始查找)

    let $arr = List.of(1,2,3,6);
    let $arr2 = $arr.delete(2);
    let $arr3 = $arr.remove(-3); // 使用remove(),功能一样
    console.log($arr.toJS());  // [1, 2, 3, 6]
    console.log($arr2.toJS()); // [1, 2, 6]
    console.log($arr3.toJS()); // [1, 3, 6]
.insert(index,value) ,(no : Map)

返回一个新的 List ,在index 的位置 插入 新数据 value,原位置数据向后移一位,(index 为负数,表示从末尾索引)

    let $arr = List.of(1,2,3,6);
    let $arr2 = $arr.insert(2,99);
    let $arr3 = $arr.insert(-3,88); 
    console.log($arr.toJS());  // [1, 2, 3, 6]
    console.log($arr2.toJS()); // [1, 2, 99, 3, 6]        
    console.log($arr3.toJS()); // [1, 88, 2, 3, 6]
.clear()

返回一个空的List或者Map

    let $arr = List.of(1,2,3,6);
    let $arr2 = $arr.clear();
    console.log($arr.toJS());  // [1, 2, 3, 6]
    console.log($arr2.toJS()); // []
.push() .pop() .unshift() .shift() (no : Map)

类似js的数组方法 尾部添加、尾部删除、头部添加、头部删除,但是不同的是,返回的是新的List

    let $arr = List.of(1,2,3,6);
    let $arr2 = $arr.push(111); 
    let $arr3 = $arr.pop(); 
    let $arr4 = $arr.unshift(1.01); 
    let $arr5 = $arr.shift(); 
    console.log($arr.toJS());  // [1, 2, 3, 6]
    console.log($arr2.toJS()); // [1, 2, 3, 6, 111]        
    console.log($arr3.toJS()); // [1, 2, 3]
    console.log($arr4.toJS()); // [1.01, 1, 2, 3, 6]
    console.log($arr5.toJS()); // [2, 3, 6]
.update()

返回更新的List或者Map

    let a = Map({a:1, b:2, c:3});
    let b = a.update('a',value => {
        return value + 10;
    });
    let c = a.update('d','no',value => {
        console.log(value); // no
        return 20;
    });
    let d = a.update(map => {
        console.log('map = ' + map); // map = Map { "a": 1, "b": 2, "c": 3 }
        return map;
    })
    console.log('b = ' + b); // b = Map { "a": 11, "b": 2, "c": 3 }
    console.log('c = ' + c); // c = Map { "a": 1, "b": 2, "c": 3, "d": 20 }
    console.log(a === b); // false
    console.log('d = ' + d); // d = Map { "a": 1, "b": 2, "c": 3 }
.merge()

用来合并,List 的合并会按照索引值替换,Map 按照 key值替换

    let $arr = List([{a:110,b:220},22,33,44]);
    let $arr2 = $arr.merge($arr, [99,{c:330, b:440}]);
    console.log($arr.toJS());  // [{a:110,b:220},22,33,44]
    console.log($arr2.toJS());  // [99,{c:330, b:440},33,44]
.mergeWith()

跟merge类似,但是可以处理逻辑,决定输出规则

    let a = Map({a:1, b:2, c:3});
    let b = Map({c:30, b:7, d:9});
    let c = a.mergeWith((prev,next) => {
        console.log(prev + '====' + next); // 3===30 2===7
        return prev / next;
    },b);
    console.log('c = ' + c); // c = Map { "a": 1, "b": 0.2857142857142857, "c": 0.1, "d": 9 }
.mergeDeep() .mergeDeepWith()

跟 merge一样,但是会深度处理

    let a = Immutable.fromJS({a:1, b:2, c:{d:33,e:44}});
    let b = Immutable.fromJS({c:{d:333, f:555}, b:7, d:9});
    let c = a.merge(b);
    let d = a.mergeDeep(b);
    let e = a.mergeDeepWith((prev, next) => {
        console.log(prev + '====' + next); // 33====333 2====7
        return prev / next;
    }, b);
    console.log('c = ' + c); 
    // c = Map { "a": 1, "b": 7, "c": Map { "d": 333, "f": 555 }, "d": 9 }       
    console.log('d = ' + d); 
    // d = Map { "a": 1, "b": 7, "c": Map { "d": 333, "e": 44, "f": 555 }, "d": 9 }       
    console.log('e = ' + e); 
    // e = Map { "a": 1, "b": 0.2857142857142857, "c": Map { "d": 0.0990990990990991, "e": 44, "f": 555 }, "d": 9 }
.setSize() (no : Map)

改变List 长度

  • 新的size小于原size,则从后边剪切
  • 新的size大于原size,则增加新的未定义的值
    let $arr = List([{a:110,b:220},22,33,44]);
    let $arr2 = $arr.setSize(7);
    let $arr3 = $arr.setSize(2);
    console.log($arr.toJS());  // [{a:110,b:220},22,33,44]
    console.log($arr2.toJS());  // [{a:110,b:220},22, 33, 44, undefined, undefined, undefined]
    console.log($arr3.toJS());  // [{a:110,b:220},22]
.setIn()

返回一个新的List或者Map 含有新设定的值

    let a = Immutable.fromJS([{a:111,b:222}, 1, 2, [3, 4]])
    let b = a.setIn([0, 'b'], -3);
    let c = a.setIn([3, 0], 100);
    console.log(b.toJS()); // [{a:111,b:-3}, 1, 2, [3, 4]]
    console.log(c.toJS()); // [{a:111,b:222}, 1, 2, [100, 4]]
.getIn()

返回一个深层次的值

    let a = Immutable.fromJS([{a:111,b:222}, 1, 2, [3, 4]])
    let b = a.getIn([0, 'b']);
    let c = a.getIn([3, 0]);
    console.log(b); // 222
    console.log(c); // 3
.hasIn()

深层次的查找,是否有相应的key

    let a = Immutable.fromJS([{a:111,b:222}, [3, 4, 5, 6]])
    let b = a.hasIn([0, 'b']);
    let c = a.hasIn([1, 4]);
    console.log(b); // true
    console.log(c); // false
.deleteIn()

返回一个删除指定值的List或者Map

    let a = Immutable.fromJS([{a:111,b:222}, 1, 2, [3, 4]])
    let b = a.deleteIn([0, 'b']);
    let c = a.deleteIn([3, 0]);
    console.log(b.toJS()); // [{a:111}, 1, 2, [3, 4]]
    console.log(c.toJS()); // [{a:111,b:222}, 1, 2, [4]]
.updateIn()

返回一个新的List或者Map

    let a = Immutable.fromJS({a:1, b:2, c:{d:33,e:44}});
    let b = a.updateIn(['c','d'],value => {
        console.log(value); // 33
        return 33333;
    });
    console.log('b = ' + b); // b = Map { "a": 1, "b": 2, "c": Map { "d": 33333, "e": 44 } }
.mergeIn() .mergeDeepIn()

查找里层,然后将里层跟新的合并

    let a = Immutable.fromJS({a:1, b:2, c:{d:{g:33,h:66},e:44}});
    let b = a.mergeIn(['c'],{d:{g:33333},f:88888});
    let c = a.mergeDeepIn(['c'],{d:{g:33333},f:88888});
    console.log('b = ' + b); 
    // b = Map { "a": 1, "b": 2, "c": Map { "d": Map { "g": 33333 }, "e": 44, "f": 88888 } }
    console.log('c = ' + c);
    // c = Map { "a": 1, "b": 2, "c": Map { "d": Map { "g": 33333, "h": 66 }, "e": 44, "f": 88888 } }
序列算法
.map()

遍历,也可以返回一个经过计算的与原类型相同的值,List Map 都可以

    let a = Immutable.fromJS({a:[1,[2,3,4],{a:11,b:22}],b:[222,333]});
    let b = a.map((x,y) => {
        console.log(x); // List、List
        console.log('---');
        console.log(y); // a 、 b
        return x.push('nn'); 
    })
    console.log(b.toJS()); // {a:Array[4],b:[222,333,"nn"]}
.filter() .filterNot()

过滤(过滤得到满足条件的、过滤得到不满足条件的)

    let a = Immutable.fromJS({a:[1,[2,3,4],{a:11,b:22}],b:[222,333]});
    let b = a.filter((x,y) => {
        return x.size >= 3; 
    })
    console.log(b.toJS()); // {a:Array[3]}
.reverse() .sort()

类似js原生的数组方法 反向重组、排序

.slice()

类似原生js数组的方法 抽取

    let a = Immutable.fromJS([1,[2,3,4],'nn',{a:11,b:22}]);
    let b = a.slice(1);
    let c = a.slice(1,3);
    console.log('b  ' + b); // b  List [ List [ 2, 3, 4 ], "nn", Map { "a": 11, "b": 22 } ]
    console.log('c  ' + c); // c  List [ List [ 2, 3, 4 ], "nn" ]
.concat()

类似原生js数组的方法 拼接

    let a = Immutable.fromJS([1,[2,3,4],'nn',{a:11,b:22}]);
    let b = a.concat(['ddd']);
    console.log('b  ' + b); // b  List [ 1, List [ 2, 3, 4 ], "nn", Map { "a": 11, "b": 22 }, "ddd" ]
.splice()

类似原生js数组的方法 替换

    let a = Immutable.fromJS([1,[2,3,4],'nn',{a:11,b:22}]);
    let b = a.splice(0,2,['pp']);
    console.log('b  ' + b); // b  List [ pp, "nn", Map { "a": 11, "b": 22 } ]
.join()

类似原生js数组的方法 链接成字符串

其他方法
.forEach()

遍历

    let a = Immutable.fromJS({a:[1,[2,3,4],{a:11,b:22}],b:[222,333]});
    a.forEach((value,key,some) => {
        console.log('value  ' + value); 
        // value  List [ 1, List [ 2, 3, 4 ], Map { "a": 11, "b": 22 } ]
        console.log('key  ' + key);
        // key  a
        console.log('some  ' + some);
        // some  Map { "a": List [ 1, List [ 2, 3, 4 ], Map { "a": 11, "b": 22 } ], "b": List [ 222, 333 ] }
    });
.rest() .butLast()

抽取 部分除了 第一个或者最后一个

    let a = Immutable.fromJS([1,[2,3,4],'nn',{a:11,b:22}]);
    let b = a.rest();
    let c = a.butLast();
    console.log('a  ' + a); // a  List [ 1, List [ 2, 3, 4 ], "nn", Map { "a": 11, "b": 22 } ]
    console.log('b  ' + b); // b  List [ List [ 2, 3, 4 ], "nn", Map { "a": 11, "b": 22 } ]
    console.log('c  ' + c); // c  List [ 1, List [ 2, 3, 4 ], "nn" ]
isEmpty()

判断是否为空

    let a = Immutable.fromJS([1,[2,3,4],'nn',{a:11,b:22}]);
    let b = Immutable.fromJS([]);
    console.log(a.isEmpty()); // false
    console.log(b.isEmpty()); // true
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值