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

資訊專欄INFORMATION COLUMN

JavaScript 數(shù)組展開以及 underscore 重要的內(nèi)部方法 flatten 詳解

binaryTree / 1987人閱讀

摘要:今天要講的是數(shù)組展開以及和數(shù)組展開息息相關(guān)的一個重要的內(nèi)部方法。也是個布爾值,當(dāng)為并且也為時,能過濾參數(shù)元素中的非數(shù)組元素。首先并不需要對數(shù)組深度展開,其次傳入的是數(shù)組,對于非數(shù)組元素可以直接忽略。

Why underscore

(覺得這一段眼熟的童鞋可以直接跳到正文了...)

最近開始看 underscore.js 源碼,并將 underscore.js 源碼解讀 放在了我的 2016 計(jì)劃中。

閱讀一些著名框架類庫的源碼,就好像和一個個大師對話,你會學(xué)到很多。為什么是 underscore?最主要的原因是 underscore 簡短精悍(約 1.5k 行),封裝了 100 多個有用的方法,耦合度低,非常適合逐個方法閱讀,適合樓主這樣的 JavaScript 初學(xué)者。從中,你不僅可以學(xué)到用 void 0 代替 undefined 避免 undefined 被重寫等一些小技巧 ,也可以學(xué)到變量類型判斷、函數(shù)節(jié)流&函數(shù)去抖等常用的方法,還可以學(xué)到很多瀏覽器兼容的 hack,更可以學(xué)到作者的整體設(shè)計(jì)思路以及 API 設(shè)計(jì)的原理(向后兼容)。

之后樓主會寫一系列的文章跟大家分享在源碼閱讀中學(xué)習(xí)到的知識。

underscore-1.8.3 源碼解讀項(xiàng)目地址 https://github.com/hanzichi/underscore-analysis

underscore-1.8.3 源碼全文注釋 https://github.com/hanzichi/underscore-analysis/blob/master/underscore-1.8.3.js/underscore-1.8.3-analysis.js

underscore-1.8.3 源碼解讀系列文章 https://github.com/hanzichi/underscore-analysis/issues

歡迎圍觀~ (如果有興趣,歡迎 star & watch~)您的關(guān)注是樓主繼續(xù)寫作的動力

flatten

端午休息三天,睡了兩天,是該有點(diǎn)產(chǎn)出了。

今天要講的是數(shù)組展開以及和數(shù)組展開息息相關(guān)的一個重要的內(nèi)部方法 flatten。

什么是數(shù)組展開?簡單的說就是將嵌套的數(shù)組 "鋪平",還是舉幾個簡單的例子吧。

[[[1, 2], [1, 2, 3]], [1, 2]] => [1, 2, 1, 2, 3, 1, 2]
[[[1, 2], [1, 2, 3]], [1, 2]] => [[1, 2], [1, 2, 3], 1, 2]

以上兩種都是數(shù)組展開,第一種我們認(rèn)為是深度展開,即打破所有嵌套數(shù)組,將元素提取出來放入一個數(shù)組中;第二種只展開了一層,即只把數(shù)組內(nèi)嵌套的一層數(shù)組展開,而沒有遞歸展開下去。

我們首先來看看 flatten 方法的調(diào)用形式。

var flatten = function(input, shallow, strict, startIndex) {
  // ...
};

第一個參數(shù) input 即為需要展開的數(shù)組,所以 flatten 方法中傳入的第一個參數(shù)肯定是數(shù)組(或者 arguments);第二個參數(shù) shallow 是個布爾值,如果為 false,則表示數(shù)組是深度展開,如果為 true 則表示只展開一層;第四個參數(shù)表示 input 展開的起始位置,即從 input 數(shù)組中第幾個元素開始展開。

var ans = flatten([[1, 2], [3, 4]], false, false, 1);
console.log(ans); // => [3, 4]

從第 1 項(xiàng)開始展開數(shù)組,即忽略了數(shù)組的第 0 項(xiàng)([1, 2])。

以上三個參數(shù)還是比較容易理解的,相對來說費(fèi)勁的是第三個參數(shù) strict。strict 也是個布爾值,當(dāng) shallow 為 true 并且 strict 也為 true 時,能過濾 input 參數(shù)元素中的非數(shù)組元素。好難理解啊!我們舉個簡單的例子。

var ans = flatten([5, 6, [1, 2], [3, 4]], true, true);
console.log(ans); // => [1, 2, 3, 4]

5 和 6 是 input 參數(shù)中的非數(shù)組元素,直接過濾掉了。如果 strict 為 true 并且 shallow 為 false,那么調(diào)用 flatten 方法的結(jié)果只能是 []。所以我們會看到源碼里如果 strict 為 true,那么 shallow 也一定是 true。

直接來看源碼,加了非常多的注釋。

var flatten = function(input, shallow, strict, startIndex) {
  // output 數(shù)組保存結(jié)果
  // 即 flatten 方法返回?cái)?shù)據(jù)
  // idx 為 output 的累計(jì)數(shù)組下標(biāo)
  var output = [], idx = 0;

  // 根據(jù) startIndex 變量確定需要展開的起始位置
  for (var i = startIndex || 0, length = getLength(input); i < length; i++) {
    var value = input[i];
    // 數(shù)組 或者 arguments
    if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) {
      // flatten current level of array or arguments object
      // (!shallow === true) => (shallow === false)
      // 則表示需深度展開
      // 繼續(xù)遞歸展開
      if (!shallow) 
        // flatten 方法返回?cái)?shù)組
        // 將上面定義的 value 重新賦值
        value = flatten(value, shallow, strict);

      // 遞歸展開到最后一層(沒有嵌套的數(shù)組了)
      // 或者 (shallow === true) => 只展開一層
      // value 值肯定是一個數(shù)組
      var j = 0, len = value.length;

      // 這一步貌似沒有必要
      // 畢竟 JavaScript 的數(shù)組會自動擴(kuò)充
      // 但是這樣寫,感覺比較好,對于元素的 push 過程有個比較清晰的認(rèn)識
      output.length += len;

      // 將 value 數(shù)組的元素添加到 output 數(shù)組中
      while (j < len) {
        output[idx++] = value[j++];
      }
    } else if (!strict) { 
      // (!strict === true) => (strict === false)
      // 如果是深度展開,即 shallow 參數(shù)為 false
      // 那么當(dāng)最后 value 不是數(shù)組,是基本類型時
      // 肯定會走到這個 else-if 判斷中
      // 而如果此時 strict 為 true,則不能跳到這個分支內(nèi)部
      // 所以 shallow === false 如果和 strict === true 搭配
      // 調(diào)用 flatten 方法得到的結(jié)果永遠(yuǎn)是空數(shù)組 []
      output[idx++] = value;
    }
  }

  return output;
};

總的來說,就是持續(xù)遞歸調(diào)用 flatten,直到不能展開為止。給出 flatten 方法的實(shí)現(xiàn)源碼位置 https://github.com/hanzichi/underscore-analysis/blob/master/underscore-1.8.3.js/src/underscore-1.8.3.js#L489-L507。

接著我們來看看源碼中有用到這個內(nèi)部方法的 API。

首先是 _.flatten 方法,非常簡單,用了 flatten 的前三個參數(shù)。

_.flatten = function(array, shallow) {
  // array => 需要展開的數(shù)組
  // shallow => 是否只展開一層
  // false 為 flatten 方法 strict 變量
  return flatten(array, shallow, false);
};

前面說了,strict 為 true 只和 shallow 為 true 一起使用,所以沒有特殊情況的話 strict 默認(rèn)為 false。

_.union 方法同樣用到了 flatten,這個方法的作用是傳入多個數(shù)組,然后對數(shù)組元素去重。

var ans = _.union([[1]], [1, 2], 3, 4);
console.log(ans); // => [[1], 1, 2]

首先并不需要對數(shù)組深度展開,其次 _.union 傳入的是數(shù)組,對于非數(shù)組元素可以直接忽略。這兩點(diǎn)直接對應(yīng)了 shallow 參數(shù)和 strict 參數(shù)均為 true(都不用做容錯處理了)。對于一個數(shù)組的去重,最后調(diào)用 _.unique 即可。

_.union = function() {
  // 首先用 flatten 方法將傳入的數(shù)組展開成一個數(shù)組
  // 然后就可以愉快地調(diào)用 _.uniq 方法了
  // 假設(shè) _.union([1, 2, 3], [101, 2, 1, 10], [2, 1]);
  // arguments 為 [[1, 2, 3], [101, 2, 1, 10], [2, 1]]
  // shallow 參數(shù)為 true,展開一層
  // 結(jié)果為 [1, 2, 3, 101, 2, 1, 10, 2, 1]
  // 然后對其去重
  return _.uniq(flatten(arguments, true, true));
};

而 _.difference,_.pick,_.omit 方法,大家可以自己進(jìn)源碼去看,都大同小異,沒什么特別要注意的點(diǎn)。(注意下 startIndex 參數(shù)即可)

對于內(nèi)部方法 flatten,我要總結(jié)的是,可能某個內(nèi)部方法會被多個 API 調(diào)用,如何設(shè)計(jì)地合理,優(yōu)雅,如何兼顧到各種情況,真的需要強(qiáng)大的實(shí)踐以及代碼能力,這點(diǎn)還需要日后多加摸索。

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

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

相關(guān)文章

  • JavaScript 數(shù)組展開(扁平化)和underscore flatten

    摘要:原文地址數(shù)組展開就是將嵌套的數(shù)組扁平化轉(zhuǎn)換為一維的判斷每一項(xiàng)是否是數(shù)組,然后遞歸遞歸調(diào)用數(shù)組在調(diào)用會將數(shù)組轉(zhuǎn)換成再執(zhí)行方法會變成還需要將所有的參數(shù)轉(zhuǎn)換為數(shù)字,所以這種方式的不足就是如果數(shù)組里面是既有數(shù)字又有字符串,會全部展開為數(shù)字轉(zhuǎn)為數(shù)字方 原文地址 數(shù)組展開就是將嵌套的數(shù)組扁平化(轉(zhuǎn)換為一維的)eg: const arr=[[[1, 2], [1, 2, 3]], [1, 2]] ...

    awokezhou 評論0 收藏0
  • underscore 源碼解讀】Object Functions 相關(guān)源碼拾遺 & 小結(jié)

    摘要:直接來看例子一目了然,第一個參數(shù)是對象,第二個參數(shù)可以是一系列的值,也可以是數(shù)組數(shù)組中含,也可以是迭代函數(shù),我們根據(jù)值,或者迭代函數(shù)來過濾中的鍵值對,返回新的對象副本。 Why underscore 最近開始看 underscore.js 源碼,并將 underscore.js 源碼解讀 放在了我的 2016 計(jì)劃中。 閱讀一些著名框架類庫的源碼,就好像和一個個大師對話,你會學(xué)到很多。...

    neuSnail 評論0 收藏0
  • 30秒就能理解 Javascript 代碼片段 --- Array篇

    摘要:而這個秒就能理解的代碼片段,摒棄了許多不必要的代碼,只實(shí)現(xiàn)了最核心的部分,不像和那樣,考慮參數(shù)邊界值問題,例如,參數(shù)的類型是否符合預(yù)期等。使用根據(jù)斷言函數(shù)對數(shù)組進(jìn)行過濾,返回條件為真值的對象。 之前翻譯過一篇文章,《我喜歡的5個編程技巧》,里面的一個技巧是借鑒一個網(wǎng)站的代碼片段,好奇的小手點(diǎn)下鏈接后,發(fā)現(xiàn)是一個有 47000 多star的倉庫,30-seconds-of-code。 倉...

    fox_soyoung 評論0 收藏0
  • underscore 源碼解讀】Array Functions 相關(guān)源碼拾遺 & 小結(jié)

    摘要:最近開始看源碼,并將源碼解讀放在了我的計(jì)劃中。將轉(zhuǎn)為數(shù)組同時去掉第一個元素之后便可以調(diào)用方法總結(jié)數(shù)組的擴(kuò)展方法就解讀到這里了,相關(guān)源碼可以參考這部分。放個預(yù)告,下一篇會暫緩下,講下相關(guān)的東西,敬請期待。 Why underscore 最近開始看 underscore.js 源碼,并將 underscore.js 源碼解讀 放在了我的 2016 計(jì)劃中。 閱讀一些著名框架類庫的源碼,就好...

    SimpleTriangle 評論0 收藏0
  • JavaScript專題之數(shù)組扁平化

    摘要:專題系列第九篇,講解如何實(shí)現(xiàn)數(shù)組的扁平化,并解析的源碼扁平化數(shù)組的扁平化,就是將一個嵌套多層的數(shù)組嵌套可以是任何層數(shù)轉(zhuǎn)換為只有一層的數(shù)組。 JavaScript 專題系列第九篇,講解如何實(shí)現(xiàn)數(shù)組的扁平化,并解析 underscore 的 _.flatten 源碼 扁平化 數(shù)組的扁平化,就是將一個嵌套多層的數(shù)組 array (嵌套可以是任何層數(shù))轉(zhuǎn)換為只有一層的數(shù)組。 舉個例子,假設(shè)有個...

    tuantuan 評論0 收藏0

發(fā)表評論

0條評論

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