• vue.js 源代码学习笔记 ----- 工具方法 share


    /* @flow */
    
    /**
     * Convert a value to a string that is actually rendered.
    { .. } [ .. ] 2 => ''
    */ export function _toString (val: any): string { return val == null ? '' : typeof val === 'object' ? JSON.stringify(val, null, 2) //2 是控制字符串系列化后的空格为2 : String(val) } /** * Convert a input value to a number for persistence. * If the conversion fails, return original string.
    刻意把 输入框的值转换成数字, 如失败, 则还原
    如 '123abc' 会转换成 123
    这里没有用parseInt 是因为parseInt对浮点型转换不准确, 如
     
      parseInt(0.0000008,10) => 8 parseFloat(0.0000008,10) => 8e-7
      而且对于字符串, parFloat只能按十进制来转换, parseInt('0200',8) => 128; parseFloat('0200',8) => 200
    */
    export function toNumber (val: string): number | string {
      const n = parseFloat(val)
      return isNaN(n) ? val : n
    }
    
    /**
     * Make a map and return a function for checking if a key
     * is in that map.
    输入标签 'div,slot,span'等, div或者slot作为一个对象的key, 返回一个函数
    检查传入的key是否在map中
    */ export function makeMap ( str: string, expectsLowerCase?: boolean //传入的key还可以不区分大小写 ): (key: string) => true | void { const map = Object.create(null) //这里没有使用 new Object 或者 = {}; 是为了创建没有 __proto__属性的 真空对象 const list: Array<string> = str.split(',') //这里用到了闭包, 把map 缓存了起来

    for (let i = 0; i < list.length; i++) { map[list[i]] = true } return expectsLowerCase ? val => map[val.toLowerCase()] : val => map[val] } /** * Check if a tag is a built-in tag.
    检查一个标签是否是 内置标签
    */ export const isBuiltInTag = makeMap('slot,component', true) /** * Remove an item from an array
    利用indexOf splice 移除一个值
    */ export function remove (arr: Array<any>, item: any): Array<any> | void { if (arr.length) { const index = arr.indexOf(item) if (index > -1) { return arr.splice(index, 1) } } } /** * Check whether the object has the property.
    缓存原型方法, 避免每次去对象的原型找这个hasOwnProperty方法, 减少一丁点性能损耗
    */ const hasOwnProperty = Object.prototype.hasOwnProperty
    export
    function hasOwn (obj: Object, key: string): boolean { return hasOwnProperty.call(obj, key) } /** * Check if value is primitive
    只有 字符串 数字 才是原始类型
    */ export function isPrimitive (value: any): boolean { return typeof value === 'string' || typeof value === 'number' } /** * Create a cached version of a pure function.
    利用闭包缓存一个函数执行特定参数的结果, 比如
    执行 var cFn1 = cached( fn1 ); cFn1(2); 第二次调用 cFn1(2)的时候, 就可以利用第一次的结果,
    适合会多次调用一个函数, 而且参数有可能重复的情况
    由于是利用了缓存, 所以传入的函数应该是纯函数, 就是每次如果参数一样, 结果必须一样, 不能是random这样的函数
    */ export function cached<F: Function> (fn: F): F { const cache = Object.create(null)
    return (function cachedFn (str: string) { const hit = cache[str] return hit || (cache[str] = fn(str)) }: any)
    }
    /** * Camelize a hyphen-delimited string.
    把 'ms-box-shadow' 这样的用-分割的连字符, 驼峰化 => msBoxShadow ; 有利于在js中设置样式
    */ const camelizeRE = /-(w)/g export const camelize = cached((str: string): string => {
    //c 就是(w)这个子项, 前面需要一个-; 所以 -box 会变成 -Box
    return str.replace(camelizeRE, (_, c) => c ? c.toUpperCase() : '') }) /** * Capitalize a string.
    abc 变成 Abc
    */ export const capitalize = cached((str: string): string => { return str.charAt(0).toUpperCase() + str.slice(1) }) /** * Hyphenate a camelCase string.
    驼峰转成链接字符 abcAb => abc-ab
    */ const hyphenateRE = /([^-])([A-Z])/g export const hyphenate = cached((str: string): string => { return str .replace(hyphenateRE, '$1-$2') //转两次? .replace(hyphenateRE, '$1-$2') .toLowerCase() }) /** * Simple bind, faster than native
    自定义的bind方法, 比原生快那么一点, 原理?
    */ export function bind (fn: Function, ctx: Object): Function { function boundFn (a) { const l: number = 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 } /** * Convert an Array-like object to a real Array.
    数组转换类数组, 这里没有用[].slice.call?
    */ export function toArray (list: any, start?: number): Array<any> { start = start || 0 let i = list.length - start
    const ret: Array
    <any> = new Array(i) //这里没使用push

    while (i--) { ret[i] = list[i + start] } return ret } /** * Mix properties into target object.
    太简单的混入
    */ export function extend (to: Object, _from: ?Object): Object { for (const key in _from) { to[key] = _from[key] } return to } /** * Quick object check - this is primarily used to tell * Objects from primitive values when we know the value * is a JSON-compliant type.
    简单判断一个对象
    */ export function isObject (obj: mixed): boolean { return obj !== null && typeof obj === 'object' } /** * Strict object type check. Only returns true * for plain JavaScript objects.
    确保是一个完全的对象, 而不是数组 null RegExp 之类的东西
    */ const toString = Object.prototype.toString const OBJECT_STRING = '[object Object]' export function isPlainObject (obj: any): boolean { return toString.call(obj) === OBJECT_STRING } /** * Merge an Array of Objects into a single Object.
    ['a','b'] => {0:'a',1:'b'}
    */ export function toObject (arr: Array<any>): Object { const res = {} for (let i = 0; i < arr.length; i++) { if (arr[i]) { extend(res, arr[i]) } } return res } /** * Perform no operation. 一个空函数 */ export function noop () {} /** * Always return false. 减少书写? */ export const no = () => false /** * Return same value 需要利用函数来返回相同值? */ export const identity = (_: any) => _ /** * Generate a static keys string from compiler modules.
    把modules的每个statickeys 链接起来 形成一个特定的静态key
    */ export function genStaticKeys (modules: Array<ModuleOptions>): string { return modules.reduce((keys, m) => { return keys.concat(m.staticKeys || []) }, []).join(',') } /** * Check if two values are loosely equal - that is, * if they are plain objects, do they have the same shape?
    判断两个对象 的值是否 相等, 而不用考虑对象地址是否相同
    var a = {}; var b = {}; looseEqual(a,b) => true,

    对于 null 和 0 false是不相等的
    */ export function looseEqual (a: mixed, b: mixed): boolean { const isObjectA = isObject(a) const isObjectB = isObject(b)
    if (isObjectA && isObjectB) { try { return JSON.stringify(a) === JSON.stringify(b) } catch (e) { // possible circular reference return a === b } } else if (!isObjectA && !isObjectB) { return String(a) === String(b) } else { return false }
    }
    //比如 arr是 [{"a":1},...] looseIndexOf( arr, {"a":1} ) => 0 export
    function looseIndexOf (arr: Array<mixed>, val: mixed): number { for (let i = 0; i < arr.length; i++) { if (looseEqual(arr[i], val)) return i } return -1 } /** * Ensure a function is called only once. 保证这个函数只调用一次

    var f = once(fn1); f(); f()没执行fn1
    */ export function once (fn: Function): Function { let called = false return () => { if (!called) { called = true fn() } } }
  • 相关阅读:
    STM32固件库和自定义工程模板
    STM32存储器映射和寄存器映射
    VScode搭建OpenCV环境
    手写数字识别——基于LeNet-5卷积网络模型
    敏感信息泄露
    Google的高级搜索——Google hack
    session fixation攻击
    认证和会话管理漏洞
    SQLmap
    基于时间型SQL盲注
  • 原文地址:https://www.cnblogs.com/dhsz/p/7064958.html
Copyright © 2020-2023  润新知