js 常用函数

//判断未定义
  function isUndef (v) {
    return v === undefined || v === null
  }
//判断已定义
  function isDef (v) {
    return v !== undefined && v !== null
  }

  function isTrue (v) {
    return v === true
  }

  function isFalse (v) {
    return v === false
  }

  /**
   *  判断为原始类型
   */
  function isPrimitive (value) {
    return (
      typeof value === 'string' ||
      typeof value === 'number' ||
      // $flow-disable-line
      typeof value === 'symbol' ||
      typeof value === 'boolean'
    )
  }

  // 判断为对象
  function isObject (obj) {
    return obj !== null && typeof obj === 'object'
  }


  
// 切割引用类型得到后面的基本类型,例如:[object RegExp] 得到的就是 RegExp
  function toRawType (value) {
let _toString = Object.prototype.toString;
    return _toString.call(value).slice(8, -1)
  }

   //判断纯粹的对象:"纯粹的对象",就是通过 {}、new Object()、Object.create(null) 创建的对象
  function isPlainObject (obj) {
  let _toString = Object.prototype.toString;
    return _toString.call(obj) === '[object Object]'
  }
  // 判断原生引用类型
  function isRegExp (v) {
  let _toString = Object.prototype.toString;
    return _toString.call(v) === '[object RegExp]'
  }

  /**
   * 检查val是否是有效的数组索引,验证是否是一个非无穷大的正整数。
   */
  function isValidArrayIndex (val) {
    let n = parseFloat(String(val));
    return n >= 0 && Math.floor(n) === n && isFinite(val)
  }
  // 判断是否是Promise
  function isPromise (val) {
    return (
      isDef(val) &&
      typeof val.then === 'function' &&
      typeof val.catch === 'function'
    )
  }

  /**
   * 将值转换为字符串。
   */
  function toString (val) {
    return val == null
      ? ''
      : Array.isArray(val) || (isPlainObject(val) && val.toString === _toString)
        ? JSON.stringify(val, null, 2)
        : String(val) 
  }

  /**
  将输入值转换为数字以便持久化。如果转换失败,则返回原始字符串。
   */
  function toNumber (val) {
    var n = parseFloat(val);
    return isNaN(n) ? val : n
  }

  /**
   *  makeMap 方法将字符串切割,放到map中,用于校验其中的某个字符串是否存在(区分大小写)于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]; }
  }
/**
   * 从数组中删除项
   */
  function remove (arr, item) {
    if (arr.length) {
      var index = arr.indexOf(item);
      if (index > -1) {
        return arr.splice(index, 1)
      }
    }
  }
/**
   * 检查对象是否具有该属性。
   * hasOwnProperty() 方法会返回一个布尔值,指示对象自身属性中是否具有指定的属性(也就是,是否有指定的键)。
   */

  function hasOwn (obj, key) {
  let hasOwnProperty = Object.prototype.hasOwnProperty;
    return hasOwnProperty.call(obj, key)
  }
 /**
   * 创建纯函数的缓存版本。
   * 高阶函数cached函数,输入参数为函数,返回值为函数。利用了闭包变量不会被回收的特点,
   * 可以缓存变量,下次再调用的时候可以从缓存中读取,如果存在缓存就使用缓存,如果不存在就重新计算下
   */
  function cached (fn) {
    var cache = Object.create(null);
    return (function cachedFn (str) {
      var hit = cache[str];
      return hit || (cache[str] = fn(str))
    })
  }
/**
   * 驼峰化一个连字符连接的字符串
   */
 
  var camelize = cached(function (str) {
 letcamelizeRE = /-(\w)/g;
    return str.replace(camelizeRE, function (_, c) { return c ? c.toUpperCase() : ''; })
  });
/**
   * 将类似数组的对象转换为实数组
   */
  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
  }
/**
   *  将多个属性插入目标的对象
   */
  function extend (to, _from) {
    for (var key in _from) {
      to[key] = _from[key];
    }
    return to
  }

  /**
   * 将对象数组合并为单个对象。
   */
  function toObject (arr) {
    var res = {};
    for (var i = 0; i < arr.length; i++) {
      if (arr[i]) {
        extend(res, arr[i]);
      }
    }
    return res
  }
 /**高级函数 对对象的浅相等进行判断
   * ES6有一个方法来判断两个对象是否相等  Object.is()  这个方法判断的是a和b是不是同一个指针的对象
   * 判断a、b两个集合是否相等,如果a包含于b,且b包含于a,则 A = B
   *判断两个对象相等 (判断两个对象键名与键值对应相同 而非指引用地址相同)
   */
  function looseEqual (a, b) {
    //判断是否恒相等
    if (a === b) { return true }
    //判断是否为对象
    var isObjectA = isObject(a);
    var isObjectB = isObject(b);
    if (isObjectA && isObjectB) {
      try {
        // 当a,b都是数组时
        var isArrayA = Array.isArray(a);
        var isArrayB = Array.isArray(b);
        if (isArrayA && isArrayB) {
          //递归判断两个数组中的每一项
          return a.length === b.length && a.every(function (e, i) {
            return looseEqual(e, b[i])
          })
          // 否则判断a,b是否为Date类型,
        } else if (a instanceof Date && b instanceof Date) {
          //使a和b恒相等
          return a.getTime() === b.getTime()
          //当a,b是对象时,首先判断length长度是否相同,长度相同再判断每个属性对应的属于值是否相同
        } else if (!isArrayA && !isArrayB) {
          var keysA = Object.keys(a);
          var keysB = Object.keys(b);
          return keysA.length === keysB.length && keysA.every(function (key) {
            return looseEqual(a[key], b[key])
          })
        } else {
          return false
        }
      } catch (e) {
        return false
      }
    } else if (!isObjectA && !isObjectB) {
      return String(a) === String(b)
    } else {
      return false
    }
  }
/**
   * 返回索引,如果没找到返回-1,否则执行looseEqual()
   */
  function looseIndexOf (arr, val) {
    for (var i = 0; i < arr.length; i++) {
      if (looseEqual(arr[i], val)) { return i }
    }
    return -1
  }
/**
   * 确保函数只调用一次。
   */
  function once (fn) {
    var called = false;
    return function () {
      if (!called) {
        called = true;
        fn.apply(this, arguments);
      }
    }
  }
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容