iT邦幫忙

2022 iThome 鐵人賽

DAY 25
0
Modern Web

前端技能樹的十萬個為什麼系列 第 25

Day 25 - 為什麼要用 Lodash

  • 分享至 

  • xImage
  •  

前言

Lodash 這一篇實在讓我不知道要放在哪啊!是一個使用範圍非常廣的函式庫,既然已經到了接近尾聲的最後幾天了,就來看看這個相當長壽的函式庫吧!

先想一下

  • Lodash 是在什麼樣的時代誕生的?
  • Lodash 怎麼解決問題?
  • Lodash 的優缺點是什麼?
  • Lodash 適合什麼情境?

Lodash 是在什麼樣的時代誕生的?

很多我們平常習以為慣的原生 function,在 ES6+ 還未推出之前,其實都還得用比較麻煩的寫法。

比如 ES7 釋出的 Array.prototype.includes() 用來判斷陣列是否包含特定的元素:

const array = [1, 2, 3];
console.log(array.includes(2)); // true

但如果在 ES7 以前的時代,想要使用這種語法,就得用到一些 polyfill 的寫法,像是這樣:

if (!Array.prototype.includes) {
  Object.defineProperty(Array.prototype, 'includes', {
    value: function(searchElement, fromIndex) {

      if (this == null) {
        throw new TypeError('"this" is null or not defined');
      }

      // 1. Let O be ? ToObject(this value).
      var o = Object(this);

      // 2. Let len be ? ToLength(? Get(O, "length")).
      var len = o.length >>> 0;

      // 3. If len is 0, return false.
      if (len === 0) {
        return false;
      }

      // 4. Let n be ? ToInteger(fromIndex).
      //    (If fromIndex is undefined, this step produces the value 0.)
      var n = fromIndex | 0;

      // 5. If n ≥ 0, then
      //  a. Let k be n.
      // 6. Else n < 0,
      //  a. Let k be len + n.
      //  b. If k < 0, let k be 0.
      var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);

      function sameValueZero(x, y) {
        return x === y || (typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y));
      }

      // 7. Repeat, while k < len
      while (k < len) {
        // a. Let elementK be the result of ? Get(O, ! ToString(k)).
        // b. If SameValueZero(searchElement, elementK) is true, return true.
        if (sameValueZero(o[k], searchElement)) {
          return true;
        }
        // c. Increase k by 1.
        k++;
      }

      // 8. Return false
      return false;
    }
  });
}

相似的 case 還滿多的,畢竟 ECMAScript 不斷推陳出新,就代表著一直有許多語法可以被優化,或者有更方便的函式釋出。但這種工具類的函式需求,從以前就在了,總不可能每個專案都要寫一大堆這種 polyfill 吧?

Lodash 怎麼解決問題?

Lodash 早在 2012 年就出現了,當時主打的是現代化 JavaScript 的工具類 library:

A modern JavaScript utility library delivering modularity, performance & extras.

主要處理的就是針對 array, number, object, string 等基本型態的迭代、操作,視為對 JavaScript 底層的功能擴充,甚至也支援 FP(Functional Programming) 的一些常用語法。

比如上面提到的 includes,使用 lodash 的話:

var array = [1, 2, 3];
console.log(_.includes(array, 2)); // true

比起 polyfill,程式碼整個簡潔許多,而我們也不需要去維護那一大堆函式庫,只要引入 Lodash,就可以直接使用許多方便的函式了。

Lodash 的價值

雖然前面舉例的 includes 在現代瀏覽器都已經有支援了,所以這時候直接用原生的 Array.prototype.includes() 就好了,如果用 _.includes 反而有點多此一舉,還得多引入一個套件。

但有些工具函式可能比較複雜,連 ECMAScript 都還沒支援,這時候 lodash 的存在就很有價值。

比如有些時候需要針對資料「深度拷貝」時,就可以用到 _.cloneDeep

var objects = [{ 'a': 1 }, { 'b': 2 }];
var deep = _.cloneDeep(objects);
console.log(deep[0] === objects[0]); // false

或者需要判斷是否為空的時候,可以用到 _.isEmpty

console.log(_.isEmpty(undefined)); // true
console.log(_.isEmpty(null)); // true
console.log(_.isEmpty('')); // true
console.log(_.isEmpty({})); // true
console.log(_.isEmpty([])); // true
console.log(_.isEmpty({a: '1'})); // false

Lodash 的優缺點是什麼?

優點

  • 開發速度提升,快速套用一些泛用性的工具函式
  • 不需要自行維護每個 polyfill function

缺點

有部分函式隨著 ECMAScript 更新,已經可以使用原生 function 來處理,可以參考 You-Dont-Need-Lodash-Underscore

Lodash 適合什麼情境?

Lodash 算是滿泛用的工具函式庫,我幾乎是在每個專案都用到XD

不過因為目前許多比較基本的 utils 都已經由 ECMAScript 實作了,使用 Lodash 的時機應該更著重在比較進階的邏輯計算,或者像是 FP 的需求,如果專案本身並不複雜,Lodash 用得不多,其實不用特地引用 Lodash 來占空間。

結語

心智圖放大版

研究 Lodash 的過程中,仔細去比對了一部份 You-Dont-Need-Lodash-Underscore 提到的函式,因為很多函式其實日常都用得很順手了,沒想過原來這些東西有一些歷史演進的脈絡,趁這個機會理解了一下每個函式的背景,以及它們的 polyfill 可以多麼複雜XD

參考資料

Lodash
You-Dont-Need-Lodash-Underscore


上一篇
Day 24 - 為什麼要用 Material-ui
下一篇
Day 26 - 為什麼要用 react-i18next
系列文
前端技能樹的十萬個為什麼30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言