immutable结构共享

导读:本篇文章讲解 immutable结构共享,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

一、深复制与浅复制
1.浅复制:引用赋值,var arr={} --> newArr=arr

2. [...]  concat  slice 都可以做深复制(只是一层深复制)

3.Object.assign()只是一层深复制,只比浅复制多深复制一层。

4.arr=[{name:'xiaoming'}] --> newArr=[...arr] --> newArr[0].name='123' --> arr=[{name:'123'}]
只是一层深复制,arr在小盒子里放了一把钥匙,newArr只是把钥匙深复制了一份放在新盒子里面,对应的指向的空间其实还是同一个空间,arr里面的对象不会被深复制

5.数组、对象深复制都好用的方法(所有结构都复制一遍)
    var arr = [{name:'mxf'}]
    const newArr = JSON.parse(JSON.stringify(arr))
    newArr[0].name='123'
    newArr --> [{name:'123'}]
    arr --> [{name:'mxf'}]
缺点:不能有undefined
    var arr = [{name:'mxf', age:undefined}]
    const newArr = JSON.parse(JSON.stringify(arr))
    newArr --> [{name:'mxf'}] // 没有age这个字段,已经丢东西了,就不叫深复制了
解决方法:
	var arr = [{name:'mxf', age:undefined}]
	写一个方法,判断传进来的数据是否是复杂数据类型的,如果是,就先把里面的元素{name:'mxf', age:undefined}进行[...]展开赋值深复制一遍,然后[{}]再进行深复制一遍。
    
6.immutable -- 深复制,受影响的字段深复制一遍,不受影响的字段复用而不是深复制,结构共享
二、immutable

作用

深复制,受影响的字段深复制一遍,不受影响的字段复用而不是深复制,结构共享,不依赖与任何库,只要有node环境就可以使用

方法

修改:Map(对象)、List(数组)
合并:merge(对象)、concat(数组)

immutable的使用

使用Map方法包裹住需要深复制的普通对象,把这个普通对象转换为immutable对象,利用set方法修改immutable对象(只修改受影响的字段)

1.一层深复制

(1)安装immutable

cnpm i --save immutable

(2)Map方法 -- 对象

// 只要以改变,就利用Map把一个普通对象,转换成一个immutable对象
const { Map } = require('immutable')

// 老状态
let prevState = {
  name: 'mxf',
  age: 100
}

let map = Map(prevState)
let newMap = map.set('name', 'xiaoming')
// map --> {"name":"mxf", "age": 100}
// newMap --> {"name":"xiaoming", "age": 100}

// 新状态,不会影响老状态
let newState = newMap.toJS()
// toJS() 把immutable转换成普通对象
// prevState --> {name:"mxf", age: 100}
// newState --> {name:"xiaoming", age: 100}

(3)List方法 -- 数组

// List结构所有的方法跟普通的数组方法是"类似"的
const { List } = require('immutable')

let prevState = ['111', '222', '333']

let arr = List(prevState)
// arr --> List['111', '222', '333']
let newArr = arr.splice(1, 1) // 不会影响老状态
// arr --> List['111', '222', '333']
// newArr --> List['111', '333']

// 装换为普通数组
let newState = newArr.toJS()
// prevState --> ['111', '222', '333']
// newState --> ['111', '333']

(4)merge方法 -- 对象

const { Map } = require('immutable')

let prevState = {
  a: 1,
  roleState: false
}

let obj2 = {
  roleState: true
}

let map = Map(prevState)
let newMap = map.merge(obj2)

let newState = newMap.toJS()
// prevState --> { a: 1, roleState: false }
// newState --> { a: 1, roleState: true }

(5)concat方法 -- 数组

const { List } = require('immutable')

let prevState = [1, 2, 3]
let arr = [4, 5, 6]

let list = List(prevState)
let newList = list.concat(arr)

let newState = newList.toJS()
console.log(prevState, newState)
// prevState --> [1, 2, 3]
// newState --> [1, 2, 3, 4, 5, 6]

2.多层深复制

fromJS方法转换为immutable结构(setIn、update方法进行修改),可以把复杂的数据结构进行immutable深复制。
const { fromJS } = require('immutable')

var prevState = {
  name: 'xiaohong',
  age: 22,
  location: {
    province: '四川',
    city: '成都',
    a: {
      b: 1
    }
  },
  list: ['111', '222', '333']
}

// 转换为immutable结构
var newMap = fromJS(prevState)
/*
  Map {
      "name": 'xiaohong',
      "age": 22,
      "location": Map {
        "province": '四川',
        "city": '成都',
        "a": Map {
          "b": 1
        }
      },
      "list": List ['111', '222', '333']
  }
*/ 

// 修改第一层结构 -- 对象
var map1 = newMap.set('name', '小明')

// 修改深层的结构 -- 属性
var map2 = newMap.setIn(['location', 'city'], '绵阳').setIn(['location', 'a', 'b'], 2)

// 修改深层的结构 -- 数组(修改)
var map3 = newMap.updateIn(['list'], data => {
  return data.splice(1, 1, '666')
})

// 转换为普通结构
var newState1 = map1.toJS()
var newState2 = map2.toJS()
var newState3 = map3.toJS()

console.log(prevState, newState1)
console.log(prevState, newState2)
console.log(prevState, newState3)

/*
  打印结果:
  newState1:
  {
    name: 'xiaohong',
    age: 22,
    location: { province: '四川', city: '成都', a: { b: 1 } },      
    list: [ '111', '222', '333' ]
  } 
  {
    name: '小明',
    age: 22,
    location: { province: '四川', city: '成都', a: { b: 1 } },      
    list: [ '111', '222', '333' ]
  }

  newState2:
  {
    name: 'xiaohong',
    age: 22,
    location: { province: '四川', city: '成都', a: { b: 1 } },      
    list: [ '111', '222', '333' ]
  } 
  {
    name: 'xiaohong',
    age: 22,
    location: { province: '四川', city: '绵阳', a: { b: 2 } },      
    list: [ '111', '222', '333' ]
  }

  newState3:
  {
    name: 'xiaohong',
    age: 22,
    location: { province: '四川', city: '成都', a: { b: 1 } },      
    list: [ '111', '222', '333' ]
  } 
  {
    name: 'xiaohong',
    age: 22,
    location: { province: '四川', city: '成都', a: { b: 1 } },      
    list: [ '111', '666', '333' ]
  }
*/ 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/4570.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!