zoukankan      html  css  js  c++  java
  • lodash chunk

    前置

    chunk 函数内部借助其他函数实现,所以从其他函数开始,chunk 在最后。

    你可能需要一些 JavaScript 基础知识才能看懂一些没有注释的细节。

    isObject

    判断是否为 Object 类型

    /**
     * Checks if `value` is the
     * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
     * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
     *
     * @since 0.1.0
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is an object, else `false`.
     * @example
     *
     * isObject({})
     * // => true
     *
     * isObject([1, 2, 3])
     * // => true
     *
     * isObject(Function)
     * // => true
     *
     * isObject(null)
     * // => false
     */
    function isObject(value) {
      const type = typeof value
      // 将 function 作为 Object 类型
      return value != null && (type === 'object' || type === 'function')
    }
    
    export default isObject
    

    getTag

    getTag 获取给定值的 toStringTag

    Symbol.toStringTag 是一个内置 symbol,它通常作为对象的属性键使用,对应的属性值应该为字符串类型,这个字符串用来表示该对象的自定义类型标签,通常只有内置的 Object.prototype.toString() 方法会去读取这个标签并把它包含在自己的返回值里。

    许多内置的 JavaScript 对象类型即便没有 toStringTag 属性,也能被 toString() 方法识别并返回特定的类型标签,比如:

    Object.prototype.toString.call('foo');     // "[object String]"
    Object.prototype.toString.call([1, 2]);    // "[object Array]"
    Object.prototype.toString.call(3);         // "[object Number]"
    Object.prototype.toString.call(true);      // "[object Boolean]"
    Object.prototype.toString.call(undefined); // "[object Undefined]"
    Object.prototype.toString.call(null);      // "[object Null]"
    // ... and more
    

    另外一些对象类型则不然,toString() 方法能识别它们是因为引擎为它们设置好了 toStringTag 标签:

    Object.prototype.toString.call(new Map());       // "[object Map]"
    Object.prototype.toString.call(function* () {}); // "[object GeneratorFunction]"
    Object.prototype.toString.call(Promise.resolve()); // "[object Promise]"
    // ... and more
    

    对于你自己创建的类,toString() 找不到 toStringTag 属性时只好返回默认的 Object 标签:

    class ValidatorClass {}
    
    Object.prototype.toString.call(new ValidatorClass()); // "[object Object]"
    

    加上 toStringTag 属性,你的类也会有自定义的类型标签了:

    class ValidatorClass {
      get [Symbol.toStringTag]() {
        return "Validator";
      }
    }
    
    Object.prototype.toString.call(new ValidatorClass()); // "[object Validator]"
    
    const toString = Object.prototype.toString
    
    /**
     * Gets the `toStringTag` of `value`.
     *
     * @private
     * @param {*} value The value to query.
     * @returns {string} Returns the `toStringTag`.
     */
    function getTag(value) {
    
      // 处理 value 能够转化为 null 的值
      if (value == null) {
        return value === undefined ? '[object Undefined]' : '[object Null]'
      }
      return toString.call(value)
    }
    
    export default getTag
    

    isSymbol

    _.isSymbol(value)
    

    检查 value 是否是原始 Symbol 或者对象

    import getTag from './.internal/getTag.js'
    
    /**
     * Checks if `value` is classified as a `Symbol` primitive or object.
     *
     * @since 4.0.0
     * @category Lang
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
     * @example
     *
     * isSymbol(Symbol.iterator)
     * // => true
     *
     * isSymbol('abc')
     * // => false
     */
    function isSymbol(value) {
      // typeof 比 Object.prototype.toString 效率高
      const type = typeof value
      return type == 'symbol' || (type === 'object' && value != null && getTag(value) == '[object Symbol]')
    }
    
    export default isSymbol
    

    toNumber

    _.toNumber(value)
    

    转换 value 为一个数字

    import isObject from './isObject.js'
    import isSymbol from './isSymbol.js'
    
    /** Used as references for various `Number` constants. */
    const NAN = 0 / 0
    
    /** Used to match leading and trailing whitespace. */
    const reTrim = /^s+|s+$/g
    
    /** Used to detect bad signed hexadecimal string values. */
    // 用于检测错误的有符号十六进制字符串值
    const reIsBadHex = /^[-+]0x[0-9a-f]+$/i
    
    /** Used to detect binary string values. */
    // 二进制。
    const reIsBinary = /^0b[01]+$/i
    
    /** Used to detect octal string values. */
    // 八进制
    const reIsOctal = /^0o[0-7]+$/i
    
    /** Built-in method references without a dependency on `root`. */
    // 不依赖于 root 的内置方法引用
    // 防止全局作用域下的parseInt被用户替换
    const freeParseInt = parseInt
    
    /**
     * Converts `value` to a number.
     *
     * @since 4.0.0
     * @category Lang
     * @param {*} value The value to process.
     * @returns {number} Returns the number.
     * @see isInteger, toInteger, isNumber
     * @example
     *
     * toNumber(3.2)
     * // => 3.2
     *
     * toNumber(Number.MIN_VALUE)
     * // => 5e-324
     *
     * toNumber(Infinity)
     * // => Infinity
     *
     * toNumber('3.2')
     * // => 3.2
     */
    function toNumber(value) {
      if (typeof value === 'number') {
        return value
      }
      if (isSymbol(value)) {
        return NAN // Number 的引用
      }
    
      // Object.prototype.valueOf() 方法返回指定对象的原始值
      // 默认情况下,valueOf方法由Object后面的每个对象继承。 
      // 每个内置的核心对象都会覆盖此方法以返回适当的值。
      // 如果对象没有原始值,则valueOf将返回对象本身。
      if (isObject(value)) {
         // value 没有 valueOf 函数或者 valueOf 函数返回一个对象,
         // 将 other 转换成 string 类型,留待后面处理。
        const other = typeof value.valueOf === 'function' ? value.valueOf() : value
        value = isObject(other) ? `${other}` : other
      }
      if (typeof value !== 'string') {
        return value === 0 ? value : +value
      }
      // @example
      // const a = function() {}
      // console.log(a.valueOf()); 
      // -> [Function: a]
      // console.log(typeof a.valueOf());  
      // -> function
      
      // @example
      // const a = {}
      // console.log(a.valueOf(); 
      // -> {}
      
      // 16进制返回NAN
      // 10进制数(+)确保返回值是数值类型
      value = value.replace(reTrim, '') // 用''替换掉字符串中符合reTrim的项
      const isBinary = reIsBinary.test(value) // 二进制
      return (isBinary || reIsOctal.test(value)) // 二进制或八进制
        ? freeParseInt(value.slice(2), isBinary ? 2 : 8) // 删除字符串前两位并解析为十进制的整数
        : (reIsBadHex.test(value) ? NAN : +value) // 十六进制字符串值返回 NAN,否则返回十进制(+)
    }
    
    export default toNumber
    

    toFinite

    _.toFinite(value)
    

    转换 value 为一个有限数字

    import toNumber from './toNumber.js'
    
    /** Used as references for various `Number` constants. */
    const INFINITY = 1 / 0 // 无穷
    const MAX_INTEGER = 1.7976931348623157e+308 // 最大整数
    
    /**
     * Converts `value` to a finite number.
     *
     * @since 4.12.0
     * @category Lang
     * @param {*} value The value to convert.
     * @returns {number} Returns the converted number.
     * @example
     *
     * toFinite(3.2)
     * // => 3.2
     *
     * toFinite(Number.MIN_VALUE)
     * // => 5e-324
     *
     * toFinite(Infinity)
     * // => 1.7976931348623157e+308
     *
     * toFinite('3.2')
     * // => 3.2
     */
    function toFinite(value) {
      // undefined & null -> 0
      if (!value) {
        return value === 0 ? value : 0
      }
      value = toNumber(value)
      // 正负无穷取正负最大值
      if (value === INFINITY || value === -INFINITY) {
        const sign = (value < 0 ? -1 : 1)
        return sign * MAX_INTEGER
      }
      return value === value ? value : 0
    }
    
    export default toFinite
    

    toInteger

    _.toInteger(value)
    

    转换 value 为一个整数

    import toFinite from './toFinite.js'
    
    /**
     * Converts `value` to an integer.
     *
     * **Note:** This method is loosely based on
     * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).
     *
     * @since 4.0.0
     * @category Lang
     * @param {*} value The value to convert.
     * @returns {number} Returns the converted integer.
     * @see isInteger, isNumber, toNumber
     * @example
     *
     * toInteger(3.2)
     * // => 3
     *
     * toInteger(Number.MIN_VALUE)
     * // => 0
     *
     * toInteger(Infinity)
     * // => 1.7976931348623157e+308
     *
     * toInteger('3.2')
     * // => 3
     */
    function toInteger(value) {
      const result = toFinite(value)
    
      // result 为小数时,则 remainder 不为 0
      const remainder = result % 1 // 余数
    
      // 抹掉小数位
      return remainder ? result - remainder : result
    }
    
    export default toInteger
    

    chunk

    _.chunk(array, [size=1])
    

    将数组拆分成多个 size 长度的区块,并将这些区块组成一个新数组。 如果array 无法被分割成全部等长的区块,那么最后剩余的元素将组成一个区块。

    import slice from './slice.js'
    import toInteger from './toInteger.js'
    
    /**
     * @since 3.0.0
     * @category Array
     * @param {Array} array The array to process.
     * @param {number} [size=1] The length of each chunk
     * @returns {Array} Returns the new array of chunks.
     * @example
     *
     * chunk(['a', 'b', 'c', 'd'], 2)
     * // => [['a', 'b'], ['c', 'd']]
     *
     * chunk(['a', 'b', 'c', 'd'], 3)
     * // => [['a', 'b', 'c'], ['d']]
     */
    function chunk(array, size = 1) {
      // 令 size >= 0
      size = Math.max(toInteger(size), 0)
    
    
      const length = array == null ? 0 : array.length
      if (!length || size < 1) {
        return []
      }
    
      // 构建新数组
      let index = 0
      let resIndex = 0
      const result = new Array(Math.ceil(length / size))
      while (index < length) {
        result[resIndex++] = slice(array, index, (index += size))
      }
    
      return result
    }
    
    export default chunk
    

    参考资料:MDN

  • 相关阅读:
    mysql外键添加error1215
    shell命令获取最新文件的名称
    centos7 apache提供文件下载
    centos7 时间设置
    微服务通信的类型
    angular-cli
    npm
    模块相关
    加油!冲冲冲
    软件评测
  • 原文地址:https://www.cnblogs.com/guangzan/p/13233111.html
Copyright © 2011-2022 走看看