lodash 源码解析 — size
前言
size
函数可以取出数组的长度、类数组对象的长度、Set
和 Map
以及对象的键值数、字符串长度等并返回
思路分析
源码分析
1. size
1. 传入参数
collection
传入对象、类数组、数组、set
、map
、string
等值
2. 源码分析
function size(collection) {
if (collection == null) {
return 0;
}
if (isArrayLike(collection)) {
return isString(collection) ? stringSize(collection) : collection.length;
}
var tag = getTag(collection);
if (tag == mapTag || tag == setTag) {
return collection.size;
}
return baseKeys(collection).length;
}
判断是否是 null
if (collection == null) {
return 0;
}
判断是否是类数组,包含 String
和 Array
if (isArrayLike(collection)) {
return isString(collection) ? stringSize(collection) : collection.length;
}
判断是否是 map
或 set
,用这两个类型的 size
属性
var tag = getTag(collection);
if (tag == mapTag || tag == setTag) {
return collection.size;
}
返回对象的 key
值
return baseKeys(collection).length;
2. stringSize
1. 传入参数
• string
普通字符串
2. 源码分析
stringSize
函数会对含有特殊 Unicode
的字符串进行区分,单独用 unicodeSize
方法判断字符串大小
function stringSize(string) {
return hasUnicode(string)
? unicodeSize(string)
: asciiSize(string);
}
3. unicodeSize
1. 传入参数
• string
含有特殊 Unicode
字符的字符串
2. 源码分析
hasUnicode
的中借助下面的正则把筛选出特定的符号:/[\u200d\ud800-\udfff\u0300-\u036f\ufe20-\ufe2f\u20d0-\u20ff\ufe0e\ufe0f]/
这组正则包含:零宽连字符、未定义区间、结合附加符号、组合用记号、变体选择符15 - 16 等,这里的主要作用的是判断出连字符等的连字组合作用,使用 unicodeSize
的主要作用就是正确的将结合连字符后的字符串的长度大小结果输出
function unicodeSize(string) {
var result = reUnicode.lastIndex = 0;
while (reUnicode.test(string)) {
++result;
}
return result;
}
4. baseKeys
1. 传入参数
• object
传入对象
2. 源码分析
function baseKeys(object) {
if (!isPrototype(object)) {
return nativeKeys(object);
}
var result = [];
for (var key in Object(object)) {
if (hasOwnProperty.call(object, key) && key != 'constructor') {
result.push(key);
}
}
return result;
}
利用 Object.keys
获取不存在原型的对象的 key
数组并返回
if (!isPrototype(object)) {
return nativeKeys(object);
}
利用 hasOwnProperty
获取存在原型的对象的 key
数组并返回
var result = [];
for (var key in Object(object)) {
if (hasOwnProperty.call(object, key) && key != 'constructor') {
result.push(key);
}
}
return result;
应用场景
通常的 size
函数肯定是用于判断传入的数组、类数组、字符串等的大小,尤其是其可以根据 Unicode
编码的含义将字符串的大小输出出来,比如下面的字符串中,\u0300
和 \u200d
是两个特殊的 Unicode
字符,分别是组合用抑音符(表现为拼音四声符号)和零宽连接符,这几个字符在连接到一起的时候会进行结合,用 size
测量大小的时候就会表现为结合后的大小,而用 length
测量会表现为有多少字符就多大
'\u0300a\u200d\u200da'.length // 5
_.size('\u0300a\u200d\u200da') // 3
'a\u0300a'.length // 3
_.size('a\u0300a') // 2
总结
size
函数是个比较简单的函数,但也有其巧妙的构思存在,最显著的就是可以根据 Unicode
的字符含义来判断字符串的长度