程序员简友广场

关于vue源码工具函数系列总结(持续更新)

2020-08-09  本文已影响0人  Splendid飞羽
工具函数封装系列(v2.6.11)
These helpers produce better VM code in JS engines due to their
explicitness and function inlining.

判断各种类型

var _toString = Object.prototype.toString;

function toRawType(value) {
    return _toString.call(value).slice(8, -1)
}

//   eg:
//   toRawType(123)
//   "Number"
//   toRawType('assasa')
//   "String"
//   toRawType({a:1})
//   "Object"
//   toRawType([1,2,3])
//   "Array"

序列化:

function toString(val) {
    return val == null
        ? ''
        : typeof val === 'object'
            ? JSON.stringify(val, null, 2)
            : String(val)
}

群组判断(重要)

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]; }
}
//eg1:是否是html标签  svg标签


var isHTMLTag = makeMap(
    'html,body,base,head,link,meta,style,title,' +
    'address,article,aside,footer,header,h1,h2,h3,h4,h5,h6,hgroup,nav,section,' +
    'div,dd,dl,dt,figcaption,figure,picture,hr,img,li,main,ol,p,pre,ul,' +
    'a,b,abbr,bdi,bdo,br,cite,code,data,dfn,em,i,kbd,mark,q,rp,rt,rtc,ruby,' +
    's,samp,small,span,strong,sub,sup,time,u,var,wbr,area,audio,map,track,video,' +
    'embed,object,param,source,canvas,script,noscript,del,ins,' +
    'caption,col,colgroup,table,thead,tbody,td,th,tr,' +
    'button,datalist,fieldset,form,input,label,legend,meter,optgroup,option,' +
    'output,progress,select,textarea,' +
    'details,dialog,menu,menuitem,summary,' +
    'content,element,shadow,template,blockquote,iframe,tfoot'
);

var isSVG = makeMap(
    'svg,animate,circle,clippath,cursor,defs,desc,ellipse,filter,font-face,' +
    'foreignObject,g,glyph,image,line,marker,mask,missing-glyph,path,pattern,' +
    'polygon,polyline,rect,switch,symbol,text,textpath,tspan,use,view',
    true
);

var isReservedTag = function (tag) {
    return isHTMLTag(tag) || isSVG(tag)
};



//eg2:这里定义了必须使用属性的判断的函数:  value这个属性的tag有:input,textarea,option,select,progress  这些标签    归属的判断


var acceptValue = makeMap('input,textarea,option,select,progress');
var mustUseProp = function (tag, type, attr) {
    return (
        (attr === 'value' && acceptValue(tag)) && type !== 'button' ||
        (attr === 'selected' && tag === 'option') ||
        (attr === 'checked' && tag === 'input') ||
        (attr === 'muted' && tag === 'video')
    )
};



//eg3:布尔值的属性的词
var isBooleanAttr = makeMap(
    'allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,' +
    'default,defaultchecked,defaultmuted,defaultselected,defer,disabled,' +
    'enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,' +
    'muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,' +
    'required,reversed,scoped,seamless,selected,sortable,translate,' +
    'truespeed,typemustmatch,visible'
);

判断字符类型

function getPathCharType(ch) {
   if (ch === undefined) {
       return 'eof';
   }

   var code = ch.charCodeAt(0);

   switch (code) {
       case 0x5B: // [
       case 0x5D: // ]
       case 0x2E: // .
       case 0x22: // "
       case 0x27: // '
       case 0x30:
           // 0
           return ch;

       case 0x5F: // _
       case 0x24:
           // $
           return 'ident';

       case 0x20: // Space
       case 0x09: // Tab
       case 0x0A: // Newline
       case 0x0D: // Return
       case 0xA0: // No-break space
       case 0xFEFF: // Byte Order Mark
       case 0x2028: // Line Separator
       case 0x2029:
           // Paragraph Separator
           return 'ws';
   }

   // a-z, A-Z
   if (code >= 0x61 && code <= 0x7A || code >= 0x41 && code <= 0x5A) {
       return 'ident';
   }

   // 1-9
   if (code >= 0x31 && code <= 0x39) {
       return 'number';
   }

   return 'else';
}

hasOwnProperty 的封装

var hasOwnProperty = Object.prototype.hasOwnProperty;
function hasOwn(obj, key) {
    return hasOwnProperty.call(obj, key)
}

hasOwn({ aaa: 1 }, 'aaa') //true

函数缓存

function cached(fn) {
    var cache = Object.create(null);
    return (function cachedFn(str) {
        var hit = cache[str];
        return hit || (cache[str] = fn(str))
    })
}

转驼峰实现 ---Camelize a hyphen-delimited string.

var camelizeRE = /-(\w)/g;
var camelize = cached(function (str) {
  return str.replace(camelizeRE, function (_, c) { return c ? c.toUpperCase() : ''; })
});
console.log(camelize('as-as'));
//as---As

自定义实现bind函数

function bind(fn, ctx) {
    function boundFn(a) {
        var l = arguments.length;
        return l
            ? l > 1
                ? fn.apply(ctx, arguments)
                : fn.call(ctx, a)
            : fn.call(ctx)
    }
    // record original fn length
    boundFn._length = fn.length;
    return boundFn
}

将字符串转成数组的 toArray 方法

function toArray(list, start) {
    start = start || 0;
    var i = list.length - start;
    var ret = new Array(i);
    while (i--) {
        ret[i] = list[i + start];
    }
    return ret
}
toArray('qwwqwq')
//["q", "w", "w", "q", "w", "q"]

extend 浅拷贝

function extend(to, _from) {
    for (var key in _from) {
        to[key] = _from[key];
    }
    return to
}
extend({ aaa: 1 }, { bbb: 1 })
//{aaa: 1, bbb: 1}

关于浏览器判断

var inBrowser = typeof window !== 'undefined';
var UA = inBrowser && window.navigator.userAgent.toLowerCase();
var isIE = UA && /msie|trident/.test(UA);
var isIE9 = UA && UA.indexOf('msie 9.0') > 0;
var isEdge = UA && UA.indexOf('edge/') > 0;
var isAndroid = UA && UA.indexOf('android') > 0;
var isIOS = UA && /iphone|ipad|ipod|ios/.test(UA);
var isChrome = UA && /chrome\/\d+/.test(UA) && !isEdge;

Set结构设置

var _Set;
/* istanbul ignore if */ // $flow-disable-line
if (typeof Set !== 'undefined' && isNative(Set)) {
    // use native Set when available.
    _Set = Set;
} else {
    // a non-standard Set polyfill that only works with primitive keys.
    _Set = /*@__PURE__*/ (function() {
        function Set() {
            this.set = Object.create(null);
        }
        Set.prototype.has = function has(key) {
            return this.set[key] === true
        };
        Set.prototype.add = function add(key) {
            this.set[key] = true;
        };
        Set.prototype.clear = function clear() {
            this.set = Object.create(null);
        };

        return Set;
    }());
}

数组的remove方法,不用再去find然后remove

function remove (arr, item) {
    if (arr.length) {
    var index = arr.indexOf(item);
    if (index > -1) {
        return arr.splice(index, 1)
    }
    }
}
上一篇 下一篇

猜你喜欢

热点阅读