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!