国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Immutable.js 初識

Olivia / 3254人閱讀

摘要:文章博客地址所創(chuàng)建的數(shù)據(jù)有一個迷人的特性數(shù)據(jù)創(chuàng)建后不會被改變。是的基類,使用該類時需要至少繼承其子類中的一個。總結(jié)所提供的和固有的各有優(yōu)勢,未來有可能制定一套原生的規(guī)范,在這之前,是一個不錯的選擇。參考資料官方文檔

文章博客地址:http://pinggod.com/2016/Immutable/

Immutable.js 所創(chuàng)建的數(shù)據(jù)有一個迷人的特性:數(shù)據(jù)創(chuàng)建后不會被改變。我們使用 Immutable.js 的示例來解釋這一特性:

var Immutable = require("immutable");

var map1 = Immutable.Map({a:1, b:2, c:3});
var map2 = map1.set("b", 50);

map1.get("b"); // 2
map2.get("b"); // 50

在上面代碼第三行中,map1 使用 set 方法更新數(shù)據(jù),結(jié)果返回一個新的 Map 類型數(shù)據(jù) map2,map2 包含了更新后的數(shù)據(jù),但是 map1 沒有發(fā)生變化。這種特性讓我們在引用數(shù)據(jù)的時候毫無后顧之憂,因為任何對數(shù)據(jù)的修改都不會影響最原始的數(shù)據(jù)。在 Immutable.js 誕生之前,我們可以使用深拷貝的方式模擬這一特性,但是會耗費過多的內(nèi)存空間和計算力。Immutable.js 相比深拷貝的優(yōu)勢在于區(qū)分發(fā)生變化的數(shù)據(jù)和未變化的數(shù)據(jù),對于上面的 map1 和 map2,b 是變化的數(shù)據(jù),所以 map1 和 map2 各保存一份 b 數(shù)據(jù),而 ac 是未變化的數(shù)據(jù),所以 map1 和 map2 仍然共享 ac 的數(shù)據(jù)。

概覽

Immutable Data 鼓勵開發(fā)者使用純函數(shù)式的開發(fā)方式,并從函數(shù)式開發(fā)中引入了惰性計算的特性。雖然加入了很多函數(shù)式的概念,Immutable.js 仍然提供了類似原生 JavaScript Array、Map 和 Set 中的方法,并且提供了在原生 JavasScript 數(shù)據(jù)和 Immutable 數(shù)據(jù)之間快速轉(zhuǎn)換的機制。

Immutable.js 的 API 主要包含以下幾部分:

formJS(),將 JavaScript Object 和 Array 徹底轉(zhuǎn)換為 Immutable Map 和 List

is(),與 Object.is() 類似都是對值的比較,但它會將 Immutable Iterable 視為值類型數(shù)據(jù)而不是引用類型數(shù)據(jù),如果兩個 Immutable Iterable 的值相等,則返回 true。與 Object.is() 不同的是,is(0, -0) 的結(jié)果為 true

List,有序索引集,類似于 JavaScript 中的 Array

Map,無序 Iterable,讀寫 Key 的復(fù)雜度為 O(log32 N)

OrderedMap,有序 Map,排序依據(jù)是數(shù)據(jù)的 set() 操作

Set,元素為獨一無二的集合,添加數(shù)據(jù)和判斷數(shù)據(jù)是否存在的復(fù)雜度為 O(log32 N)

OrderedSet,有序 Set,排序依據(jù)是數(shù)據(jù)的 add 操作。

Stack,有序集合,且使用 unshift(v)shift() 進行添加和刪除操作的復(fù)雜度為 O(1)

Range(),返回一個 Seq.Indexed 類型的數(shù)據(jù)集合,該方法接收三個參數(shù) (start = 1, end = infinity, step = 1),分別表示起始點、終止點和步長,如果 start 等于 end,則返回空的數(shù)據(jù)結(jié)合

Repeat(),返回一個 Seq.indexed 類型的數(shù)據(jù)結(jié)合,該方法接收兩個參數(shù) (value,times),value 表示重復(fù)生成的值,times 表示重復(fù)生成的次數(shù),如果沒有指定 times,則表示生成的 Seq 包含無限個 value

Record,用于衍生新的 Record 類,進而生成 Record 實例。Record 實例類似于 JavaScript 中的 Object 實例,但只接收特定的字符串作為 key,且擁有默認(rèn)值

Seq,序列(may not be backed by a concrete data structure)

Iterable,可以被迭代的 (Key, Value) 鍵值對集合,是 Immutable.js 中其他所有集合的基類,為其他所有集合提供了 基礎(chǔ)的 Iterable 操作函數(shù)(比如 map()filter

Collection,創(chuàng)建 Immutable 數(shù)據(jù)結(jié)構(gòu)的最基礎(chǔ)的抽象類,不能直接構(gòu)造該類型

1. fromJS()
Immutable.fromJS({a: {b: [10, 20, 30]}, c: 40}, function (key, value) {
    var isIndexed = Immutable.Iterable.isIndexed(value);
    return isIndexed ? value.toList() : value.toOrderedMap();
});
// true, "b", {b: [10, 20, 30]}
// false, "a", {a: {b: [10, 20, 30]}, c: 40}
// false, "", {"": {a: {b: [10, 20, 30]}, c: 40}}

fromJS() 的使用方式類似于 JSON.parse(),接收兩個參數(shù):json 數(shù)據(jù)和 reviver 函數(shù)。

2. List
List(): List
List(iter: Iterable.Indexed): List
List(iter: Iterable.Set): List
List(iter: Iterable.Keyed): List
List(array: Array): List
List(iterator: Iterator): List
List(iterable: Object): List

List() 是一個構(gòu)造方法,可以用于創(chuàng)建新的 List 數(shù)據(jù)類型,上面代碼演示了該構(gòu)造方法接收的參數(shù)類型,此外 List 擁有兩個靜態(tài)方法:

List.isList(value),判斷 value 是否是 List 類型

List.of(...values),創(chuàng)建包含 ...values 的列表

下面演示幾個 List 常用的操作,更詳細的 API 說明請參考官方文檔:

// 1. 查看 List 長度
const $arr1 = List([1, 2, 3]);
$arr1.size
// => 3

// 2. 添加或替換 List 實例中的元素
// set(index: number, value: T)
// 將 index 位置的元素替換為 value,即使索引越界也是安全的
const $arr2 = $arr1.set(-1, 0);
// => [1, 2, 0]
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 位置插入 value
const $arr5 = $arr1.insert(1, 1.5);
// => [ 1, 1.5, 2, 3 ]

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

Map 可以使用任何類型的數(shù)據(jù)作為 Key 值,并使用 Immutable.is() 方法來比較兩個 Key 值是否相等:

Map().set(List.of(1), "listofone").get(List.of(1));
// => "listofone"

但是使用 JavaScript 中的引用類型數(shù)據(jù)(對象、數(shù)組)作為 Key 值時,雖然有時兩個 Key 很像,但它們也是兩個不同的 Key 值:

console.log(Map().set({}, 1).get({}))
// => undefined

Map() 是 Map 類型的構(gòu)造方法,行為類似于 List(),用于創(chuàng)建新的 Map 實例,此外,還包含兩個靜態(tài)方法:Map.isMap() 和 Map.of()。下面介紹幾個 Map 實例的常用操作,更詳細的 API 使用說明請參考官方文檔:

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

// 2. 添加或替換 Map 實例中的元素
// set(key: K, value: V)
const $map2 = $map1.set("a", 2);
// => Map { "a": 2 }

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

// 4. 清空 Map 實例
const $map4 = $map1.clear();
// => Map {}

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

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

OrderedMap 是 Map 的變體,它除了具有 Map 的特性外,還具有順序性,當(dāng)開發(fā)者遍歷 OrderedMap 的實例時,遍歷順序為該實例中元素的聲明、添加順序。

4. Set

Set 和 ES6 中的 Set 類似,都是沒有重復(fù)值的集合,OrderedSet 是 Set 的遍歷,可以保證遍歷的順序性。

// 1. 創(chuàng)建 Set 實例
const $set1 = Set([1, 2, 3]);
// => Set { 1, 2, 3 }

// 2. 添加元素
const $set2 = $set1.add(1).add(4);
// => Set { 1, 2, 3, 4 }

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

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

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

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

Stack 是基于 Signle-Linked List 實現(xiàn)的可索引集合,使用 unshift(v)shift() 執(zhí)行添加和刪除元素的復(fù)雜度為 O(1)

// 1. 創(chuàng)建 Stack 實例
const $stack1 = Stack([1, 2, 3]);
// => Stack [ 1, 2, 3 ]

// 2. 取第一個元素
$stack1.peek()
// => 1

// 2. 取任意位置元素
$stack1.get(2)
// => 3

// 3. 判斷是否存在
$stack1.has(10)
// => false
6. Range() 和 Repeat()

Range(start?, end?, step?) 接收三個可選參數(shù),使用方法如下:

// 1. 不傳參
Range();
// => Range [ 0...Infinity ]

// 2. 設(shè)置 start 起點
Range(10);
// => Range [ 10...Infinity ]

// 3. 設(shè)置 start 起點和 end 終點
Range(10, 20);
// => Range [ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 ]

// 4. 設(shè)置 start 起點、end 終點和 step 步長
Range(10, 20, 3);
// => Range [ 10, 13, 16, 19 ]

Repeat(value, times?) 接收兩個參數(shù),其中 times 重復(fù)次數(shù)是可選參數(shù):

Repeat("foo");
// => Repeat [ foo Infinity times ]

Repeat("foo", 3);
// => Repeat [ foo 3 times ]

類似 Range()Repeat(value) 這樣生成無限長度集合的操作,內(nèi)部都存在惰性計算的機制,只有真實取值時才會生成相應(yīng)的結(jié)果。使用 ES6 中的 Generator 函數(shù),可以輕松實現(xiàn)一個惰性計算:

function* bigArr() {
    for (let i = 0; i < 100000; i++) {
        console.log(`bigArr(${i}): ${i}`)
        yield i;
    }
}

const arr = bigArr();

for (let i = 0; i < 10; i++) {
    console.log(arr.next());
}
// bigArr(0): 0
// => { value: 0, done: false }
// => bigArr(1): 1
// => { value: 1, done: false }
// => bigArr(2): 2
// => { value: 2, done: false }
// => bigArr(3): 3
// => { value: 3, done: false }
// => bigArr(4): 4
// => { value: 4, done: false }
// => bigArr(5): 5
// => { value: 5, done: false }
// => bigArr(6): 6
// => { value: 6, done: false }
// => bigArr(7): 7
// => { value: 7, done: false }
// => bigArr(8): 8
// => { value: 8, done: false }
// => bigArr(9): 9
// => { value: 9, done: false }
7. Record

Record 在表現(xiàn)上類似于 ES6 中的 Class,但在某些細節(jié)上還有所不同。通過 Record() 可以創(chuàng)建一個新的 Record 類,使用該類可以創(chuàng)建具體的 Record 實例,該實例包含在 Record() 構(gòu)造函數(shù)中聲明的所有屬性和默認(rèn)值。如果 Record 實例中的某個屬性被刪除了,則只會講實例中的屬性值恢復(fù)為默認(rèn)值:

// 1. 創(chuàng)建 Record 實例
const A = Record({ a: 1, b: 2 });
const r = new A({ a: 3 });
// => Record { "a": 3, "b": 2 }

// 2. 刪除實例屬性
const rr = r.remove("a");
// => Record { "a": 1, "b": 2 }

此外,Record 實例還具有擴展性:

class ABRecord extends Record({a:1,b:2}) {
  getAB() {
    return this.a + this.b;
  }
}

var myRecord = new ABRecord({b: 3})
myRecord.getAB()
// => 4
8. Seq

Seq 有兩個特點:immutable,一旦創(chuàng)建就不能被修改;lazy,惰性求值。在下面的代碼中,雖然組合了多種遍歷操作,但實際上并不會有任何的求值操作,只是純粹的聲明一個 Seq:

var oddSquares = Immutable.Seq.of(1,2,3,4,5,6,7,8)
    .filter(x => x % 2)
    .map(x => x * x);

如果要從 oddSquares 中取出索引為 1 的元素,則執(zhí)行過程為:

console.log(oddSquares.get(1));

// filter(1)
// filter(2)
// filter(3)
// map(3)
// => 9

Seq() 是 Seq 的構(gòu)造方法,它根據(jù)傳入的參數(shù)類型,輸出響應(yīng)的 Seq 類型:

輸入 Seq,輸出 Seq

輸入 Iterable,輸出同類型的 Seq(Keyed, Indexed, Set)

輸入 Array-like,輸出 Seq.Indexed

輸入附加 Iterator 的 Object,輸出 Seq.Indexed

輸入 Iterator,輸出 Seq。indexed

輸入 Object,輸出 Seq.Keyed

默認(rèn)情況下 Seq 的惰性計算結(jié)果不會被緩存,比如在下面的代碼中,由于每個 join() 都會遍歷執(zhí)行 map,所以 map 總共執(zhí)行了六次:

var squares = Seq.of(1,2,3).map(x => x * x);
squares.join() + squares.join();

如果開發(fā)者知道 Seq 的結(jié)果會被反復(fù)用到,那么就可以使用 cacheResult() 將惰性計算的結(jié)果保存到內(nèi)存中:

var squares = Seq.of(1,2,3).map(x => x * x).cacheResult();
squares.join() + squares.join();
9. Iterable 和 Collection

Iterable 是鍵值對形式的集合,其實例可以執(zhí)行遍歷操作,是 immutable.js 中其他數(shù)據(jù)類型的基類,所有擴展自 Iterable 的數(shù)據(jù)類型都可以使用 Iterable 所聲明的方法,比如 map 和 filter 等。

Collection 是 Concrete Data Structure 的基類,使用該類時需要至少繼承其子類中的一個:Collection.Keyed / Collection.Indexed / Collection.Set。

React

在 React 官方文檔的《Advanced Performance》 一節(jié)中,專門對 React 的性能瓶頸、優(yōu)化方式做了詳細的解析。當(dāng)一個 React 組件的 props 和 state 發(fā)生變化時,React 會根據(jù)變化后的 props 和 state 創(chuàng)建一個新的 virtual DOM,然后比較新舊兩個 vritual DOM 是否一致,只有當(dāng)兩者不同時,React 才會將 virtual DOM 渲染真實的 DOM 結(jié)點,而對 React 進行性能優(yōu)化的核心就是減少渲染真實 DOM 結(jié)點的頻率,間接地指出開發(fā)者應(yīng)該準(zhǔn)確判斷 props 和 state 是否真正發(fā)生了變化。

在比對新舊 vritual DOM 和渲染真實 DOM 前,React 為開發(fā)者提供了 shouldComponentUpdate() 方法中斷接下來的比對和渲染操作,默認(rèn)情況下,該方法總會返回 true,如果它返回 false,則不執(zhí)行比對和渲染操作:

// 最簡單的實現(xiàn):
shouldComponentUpdate (nextProps) {
    return this.props.value !== nextProps.value;
}

看起來挺簡單,實在不然。當(dāng)我們需要比對的值是對象、數(shù)組等引用值時,就會出現(xiàn)問題:

// 假設(shè) this.props.value 是 { foo: "bar" }
// 假設(shè) nextProps.value 是 { foo: "bar" },
// 顯然這兩者引用的內(nèi)存地址不同,但它們具有相同的值,這種時候不應(yīng)該繼續(xù)執(zhí)行渲染
this.props.value !== nextProps.value; // true

如果數(shù)據(jù)是 Immutable Data 的話,那么數(shù)據(jù)發(fā)生變化就會生成新的對象,開發(fā)者只需要檢查對象應(yīng)用是否發(fā)生變化即可:

var SomeRecord = Immutable.Record({ foo: null });
var x = new SomeRecord({ foo: "bar"  });
var y = x.set("foo", "baz");
x === y; // false

處理這一問題的另一種方式是通過 setter 設(shè)置 flag 對臟數(shù)據(jù)進行檢查,但冗雜的代碼是在讓人頭疼。

總結(jié)

Immutable.js 所提供的 Immutable Data 和 JavaScript 固有的 Mutable Data 各有優(yōu)勢,未來 ECAMScript 有可能制定一套原生的 Immutable Data 規(guī)范,在這之前,Immutable.js 是一個不錯的選擇。之前已經(jīng)寫文章熟悉過 Lodash 這一工具庫,Immutable 內(nèi)部也封裝了諸多常用的數(shù)據(jù)操作函數(shù),所以如果讓我來選擇的話,在 React 技術(shù)棧中我會更偏愛 Immutable。

參考資料

Immutable.js 官方文檔

React: Advanced Performance

Introduction to Immutable.js and Functional Programming Concepts

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/79959.html

相關(guān)文章

  • immutable.js初識

    摘要:介紹按照官網(wǎng)的定義是指一旦被創(chuàng)造后,就不可以被改變的數(shù)據(jù)。很多場景下,對于屬性相同的對象,我們希望相等性判斷為。和都有一個名為方法,用來處理深度對象的比較。之于的好處眾所周知,性能優(yōu)化的核心在于處理方法來避免不必要的渲染。 介紹 按照官網(wǎng)的定義, Immutable Data是指一旦被創(chuàng)造后,就不可以被改變的數(shù)據(jù)。 相等性判斷 JavaScript提供三種不同的值比較操作: 嚴(yán)格相等...

    AdolphLWQ 評論0 收藏0
  • SegmentFault 技術(shù)周刊 Vol.16 - 淺入淺出 JavaScript 函數(shù)式編程

    摘要:函數(shù)式編程,一看這個詞,簡直就是學(xué)院派的典范。所以這期周刊,我們就重點引入的函數(shù)式編程,淺入淺出,一窺函數(shù)式編程的思想,可能讓你對編程語言的理解更加融會貫通一些。但從根本上來說,函數(shù)式編程就是關(guān)于如使用通用的可復(fù)用函數(shù)進行組合編程。 showImg(https://segmentfault.com/img/bVGQuc); 函數(shù)式編程(Functional Programming),一...

    csRyan 評論0 收藏0
  • 深入理解js

    摘要:詳解十大常用設(shè)計模式力薦深度好文深入理解大設(shè)計模式收集各種疑難雜癥的問題集錦關(guān)于,工作和學(xué)習(xí)過程中遇到過許多問題,也解答過許多別人的問題。介紹了的內(nèi)存管理。 延遲加載 (Lazyload) 三種實現(xiàn)方式 延遲加載也稱為惰性加載,即在長網(wǎng)頁中延遲加載圖像。用戶滾動到它們之前,視口外的圖像不會加載。本文詳細介紹了三種延遲加載的實現(xiàn)方式。 詳解 Javascript十大常用設(shè)計模式 力薦~ ...

    caikeal 評論0 收藏0

發(fā)表評論

0條評論

Olivia

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<