JavaScript 中的對象通常是可變的,由於使用了引用賦值,新的對象簡單的引用了原始對象,改變新的對象將影響到原始對象。
例:
react
當你打印原始的A時,你會發現
dom
雖然這樣作能夠節約內存,但當應用複雜後,數據會變得很很差操控。爲了解決這個問題,通常的作法是使用淺拷貝或深拷貝來避免被修改,但這樣會形成內存的浪費。性能
Immutable Data就是一旦建立,就不能再被更改的數據。對Immutable對象的任何增刪改操做都會返回一個新的 對象,且舊對象不變。Immutable能夠很好的避免深拷貝遍歷節點帶來的性能損耗,它運用告終構共享原則,即若是對象樹中一個節點發生變化,只修改這個節點和受它影響的父節點,其它節點則進行共享。this
reacr的淺複製spa
this.state = { label : 1, value : "ccc" } ... render( const { label, value } = this.state; return( <div> label: { label }, value: { value } </div> ) )
const 就是一次淺複製,一般用於在渲染的時候提供一些變化的值,這樣不須要咱們在render中對某個變量進行其餘操做。因此在明確只是淺複製的狀況下,儘可能使用const定義變量,由於const定義的變量不能被賦值或更改,這樣就能夠避免不當心改變了該變量而引發問題。淺複製的好處就是能夠有效的節約內存地址,避免沒必要要的內存浪費。code
this.state = { value: { a: 1 } } const { value } = this.state;//淺複製 value.a = 2; console.log(this.state.value.a);//輸出2,但dom不更新 this.setState({ value });//dom更新
這裏 value.a = 2 雖然已經改變了state中value的值,但因爲是淺複製,新舊value指向的是同一塊內存地址,組件更新時(state,props改變)默認只比較新舊對象的內存地址是否一致,若是一致則不更新。同理,若是在reducer中,直接對當前的state進行修改並返回props,相應的調用該props的組件不會更新渲染。對象
const initialState = { count: 1 } function reducer(state = initialState, action){ switch(action.type){ case ADD_COUNT: state.count += 1; return { ...state }; //state改變,用到該state的組件不更新渲染 default: return state; } }
基於組件更新的原理,即比較新舊state或props是否指向同一塊內存地址,若是是則不更新,若是不是則更新。也就是說就算是兩個對象的值相等但不指向同一地址,dom也會從新渲染。這並非咱們想要看到的,咱們須要的是當props的值改變的時候dom從新渲染。咱們能夠在shouldComponentUpdate()方法裏面定義dom是否更新的條件,如 if ( props === nextProps ) return true。blog
react深複製圖片
以前談到的深複製基本是隻能複製一層變量,或者必須嵌套着複製多層變量。若是想要更方便的徹底複製一個對象,咱們可使用如下方法。ip