vue中的一些工具方法

  1. 类型判断
/**
 * Get the raw type string of a value, e.g., [object Object].
 */
const _toString = Object.prototype.toString

export function toRawType (value: any): string {
  return _toString.call(value).slice(8, -1)
}
  1. 生成字符串
/**
 * Convert a value to a string that is actually rendered.
 */
export function toString {
  return val == null
    ? ''
    : Array.isArray(val) || (toRawType(val)==='Object' && val.toString === _toString)
      ? JSON.stringify(val, null, 2) // 粗略的将引用类型转换为 JSON
      : String(val) // 粗略的将 基本类型 值 转换成 字符串
}

3.创建一个缓存机制的函数

/**
 * Create a cached version of a pure function.
 * 
 * 面试经常会面到的方法: 生成带有缓存的 函数 ( 闭包的应用 )
 */
export function cached() {
  const cache = Object.create(null)
  return (function cachedFn () {
    const hit = cache[str] // 如果已缓存, hit 就是有数据的, 如果为缓存 hit 就是 undefined
    return hit || (cache[str] = fn(str))
  })
}

4.a-b转驼峰aB

/**
 * Camelize a hyphen-delimited string.
 */
const camelizeRE = /-(\w)/g
export const camelize = cached((str: string): string => {
  return str.replace(camelizeRE, (_, c) => c ? c.toUpperCase() : '')
})
  1. 驼峰aBa-b
/**
 * Hyphenate a camelCase string.
 */
const hyphenateRE = /\B([A-Z])/g
export const hyphenate = cached(() => {
  return str.replace(hyphenateRE, '-$1').toLowerCase()
})
  1. 判断两个值是否相等;包括引用类型
    // 在面试中可能会遇到, 思想重要
// 比较两个对象是否是相等的 两个对象
// 1. js 中对象是无法使用 == 来比较的, 比是地址
// 2. 我们一般会定义如果对象的各个属性值都相等 那么对象就是相等的对象. 例如: {} 就与 {} 相等.
// 算法描述
// 1. 假定对象 a 和 b
// 2. 遍历 a 中的成员, 判断是否每一个 a 中的成员都在 b 中. 并且 与 b 中的对应成员相等.
// 3. 再遍历 b 中的成员, 判断是否每一个 b 中的成员都在 a 中. 并且 与 a 中的对应成员相等.
// 4. 如果成员是引用类型, 递归.

// 抽象一下, 判断两个集合是否相等

/**
 * Check if two values are loosely equal - that is,
 * if they are plain objects, do they have the same shape?
 */
export function looseEqual (a: any, b: any): boolean {
  if (a === b) return true
  const isObjectA = isObject(a)
  const isObjectB = isObject(b)
  if (isObjectA && isObjectB) {
    try {
      const isArrayA = Array.isArray(a)
      const isArrayB = Array.isArray(b)
      if (isArrayA && isArrayB) {
        return a.length === b.length && a.every((e, i) => {
          return looseEqual(e, b[i]) // b 包含 a
        })
      } else if (a instanceof Date && b instanceof Date) {
        return a.getTime() === b.getTime() // 单独处理 Date 类型, 时间戳应该是一样的
      } else if ( 0 ) {
        // 如果需要考虑其它类型, 添加 if 即可
      } else if (!isArrayA && !isArrayB) {
        const keysA = Object.keys(a)
        const keysB = Object.keys(b)
        // 先判断 key 的长度, 再判断 a 包含于 b
        return keysA.length === keysB.length && keysA.every(key => {
          return looseEqual(a[key], b[key])
        })
      } else {
        /* istanbul ignore next */
        return false
      }
    } catch (e) {
      /* istanbul ignore next */
      return false
    }
  } else if (!isObjectA && !isObjectB) {
    return String(a) === String(b)
  } else {
    return false
  }
}
  1. 事件触发一次
// 让一个事件 ( 一个函数 ) 只允许调用一次
// 在 vue 中有函数方法 ( on, off 等, once ), once 事件就是这个思路
/**
 * Ensure a function is called only once.
 */
export function once (fn: Function): Function {
  let called = false // 是否调用过
  return function () {
    if (!called) {
      called = true
      fn.apply(this, arguments)
    }
  }
} 
  1. 在vue模版中使用user.userInfo.userName,是如何找到对应的值;
// 分析
// 通过对. 进行分割得到一个类似于['xxx','yyy','zzz']的数组,然后对其进行遍历 
let res = null;
res = obj[path[0]];
res = res[path[1]];
res = res[path[2]];
以此规律...


let getValueByPath = (obj,pathStr)=>{
    let pathArr = pathStr.split('.');
    let result = obj,pop;
    while(pop = pathArr.shift()){
        result = result[pop];
    }
    return result;
}
// 利用函数柯理化进行优化
let createGetValueByPath = (pathStr)=>{
let pathArr = pathStr.split('.');
    return getValueByPath=(obj)=>{
        let result = obj,pop;
    while(pop = pathArr.shift()){
        result = result[pop];
    }
    return result; 
    }
}
  1. 利用函数柯里化进行tag判断是否为html标签
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'
);
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]; }
}

//这样能够大大的提高了匹配的效率以及性能
posted @ 2020-05-16 15:37  Devin_n  阅读(335)  评论(0编辑  收藏  举报