Vue源碼makeMap函數深入分析

前言

創建一個map,返回一個檢查key是否在map中的函數

主要用途: 判斷標簽是原生組件還是自定義組件,直接通過map這種key-value一一對應的數據結構,實現快速判斷

  /**
   * Make a map and return a function for checking if a key
   * is in that map.
   */
function makeMap (
    str,
    expectsLowerCase
  ) {
    var map = Object.create(null);
    var list = str.split(',');
    for (var i = 0; i < list.length; i++) {
      map[list[i]] = true;
    }
    return expectsLowerCase
      ? function (val) { return map[val.toLowerCase()]; }
      : function (val) { return map[val]; }
  }

參數解釋

str:(字符串類型)

所傳入需要創建map的字符串

expectsLowerCase:(佈爾型)

是否需要全部轉為小寫——也就是說,str中出現非小寫字母 則不需要

若沒傳,則為undefined為falsy——假值(也就不會觸發小寫轉換方法)

源碼解釋

首先通過Object.create創建一個對象,將傳入的字符串str以,分隔,生成一個list數組

對list數組進行循環,通過[list[i]]創建一個key-value的map

  • key:為字符串類型
  • value:全部為true——佈爾類型

判斷函數參數expectsLowerCase是否true

  • true——返回一個忽略大小寫,判斷key是否存在的函數
  • false——返回一個判斷key是否存在的函數

源碼疑問

為什麼這裡使用Object.create創建一個對象,而不直接使用{ }創建呢?

我們來做一個實驗就明白瞭

這裡直接用瀏覽器的控制臺實驗

var objA = Object.create(null)

首先我們創建一個objA——通過Object.create(null)

打印出來看看

然後在創建一個objB,直接賦值{}

我們發現直接通過Object.create(null)創建的東西,十分幹凈,也不存在原型鏈和原型方法

而通過{ }創建出來的東西,很明顯出現瞭很多不需要的屬性

小結:

使用Object.create條件:

  • 需要一個非常幹凈和高可定制的對象
  • 無需使用Object原型鏈中的方法

在其他正常情況下,直接使用{ }即可

很顯然,源碼這裡是需要創建一個非常幹凈的對象,從而使用的Object.create方法

為什麼使用[ ]訪問屬性

對象獲取屬性的方法有兩種,當然還可以直接使用對象解構獲取屬性

  • 點屬性訪問器
  • 方括號屬性訪問器

我們做一個實驗區別兩者,看看為啥尤大大要這麼使用

首先我們先創建一個obj

var objA = Object.create(null)

訪問不存在的屬性

當我們使用點屬性訪問器訪問一個不存在的屬性時,結果是undefined

現在試試使用方括號訪問器試試

沒想到居然直接報錯瞭

報錯的信息是x 沒被定義,看來是把x當成變量瞭

那我們直接使用字符串試試

結果居然也和.訪問結果一致瞭!!

動態創建屬性

現在我們使用點屬性訪問器去創建一個不存在的屬性時

使用方括號屬性訪問器創建時,結果一致

通過變量訪問

定義一個temp變量,存放我們需要訪問的key

var temp = 'x'

我們現在使用.訪問這個變量

結果居然發現,這個東西的結果和訪問不存在屬性一樣

而通過[]訪問時

結果就是訪問temp所代表的x

小結:

點屬性訪問器:

  • 直接訪問.後面的值——因此不支持變量訪問

方括號屬性訪問器

  • 訪問不存在變量時,若不是變量,需要以字符串形式出現
  • 支持變量訪問

當然因為這裡是需要直接動態的獲取數組的內容,相當於

  • 需要動態的創建一個不存在的
  • 屬性屬性是一個變量

因此,選擇使用方括號屬性選擇器

到此這篇關於Vue源碼makeMap函數深入分析的文章就介紹到這瞭,更多相關Vue makeMap函數內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: