首页 > 编程语言 >源码共读|vue2 工具函数

源码共读|vue2 工具函数

时间:2023-04-19 19:33:13浏览次数:47  
标签:function return val 共读 value 源码 export vue2 any

前言

本期源码共读的课程是学习 vue2 中的工具函数,学习优秀开源项目的代码的写作思路,看看他们在书写代码中都会考虑到那些问题。

资源:

学习目标

  • 分析源码
  • 学习源码中优秀代码和思想

分析源码

代码使用 Typescript 编写,如果你对 TS 不熟悉,我们可以阅读打包后的源码的 14-379 行之间的代码。

1. emptyObject

export const emptyObject: Record<string, any> = Object.freeze({})

Object.freeze() 方法将此对象转换为一个冻结对象,即不能再添加新的属性,不能修改已有属性的值,不能删除已有属性。 Record<string, any> 是 TypeScript 中的一个泛型类型,它表示一个对象,其属性名为字符串,属性值为任何类型。

2. 一些判断

  • isArray 判断是否为数组
  • isUndef 判断变量是否未被定义,如果未被定义返回true
  • isDef 判断变量是否被定义,如果未被定义返回true
  • isTrue 判断是否为真值
  • isFalse 判断是否为假值
  • primitive 判断是否为基本类型
  • isFunction 判断是否为 Function 类型
  • isObject 判断是否为非基本类型

export const isArray = Array.isArray

// These helpers produce better VM code in JS engines due to their
// explicitness and function inlining.
export function isUndef(v: any): v is undefined | null {
  return v === undefined || v === null
}

export function isDef<T>(v: T): v is NonNullable<T> {
  return v !== undefined && v !== null
}

export function isTrue(v: any): boolean {
  return v === true
}

export function isFalse(v: any): boolean {
  return v === false
}

/**
 * Check if value is primitive.
 */
export function isPrimitive(value: any): boolean {
  return (
    typeof value === 'string' ||
    typeof value === 'number' ||
    // $flow-disable-line
    typeof value === 'symbol' ||
    typeof value === 'boolean'
  )
}

export function isFunction(value: any): value is (...args: any[]) => any {
  return typeof value === 'function'
}

/**
 * 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: any): boolean {
  return obj !== null && typeof obj === 'object'
}

3.严格对象类型检查

JS 有如下几种内置的类型检查方法:

  • typeof 运算符 能够识别基本类型,但是对于引用类型都会返回 Object

    let x = 5;
    console.log(typeof x); // Output: "number"
    
  • instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。

    let arr = [1, 2, 3];
    console.log(arr instanceof Array);  // Output: true
    
    

查看源码:

/**
 * 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)
}

/**
 * Strict object type check. Only returns true
 * for plain JavaScript objects.
 */
export function isPlainObject(obj: any): boolean {
  return _toString.call(obj) === '[object Object]'
}

export function isRegExp(v: any): v is RegExp {
  return _toString.call(v) === '[object RegExp]'
}

/**
 * Check if val is a valid array index.
 */
export function isValidArrayIndex(val: any): boolean {
  const n = parseFloat(String(val))
  return n >= 0 && Math.floor(n) === n && isFinite(val)
}

export function isPromise(val: any): val is Promise<any> {
  return (
    isDef(val) &&
    typeof val.then === 'function' &&
    typeof val.catch === 'function'
  )
}

这部分的源码主要用于检查对象是否为每一个具体的类型,Array ,Object,Funtion.

4.转换

源码:


/**
 * 将值转换为实际呈现的字符串
 */
export function toString(val: any): string {
  return val == null
    ? ''
    : Array.isArray(val) || (isPlainObject(val) && val.toString === _toString)
    ? JSON.stringify(val, null, 2)
    : String(val)
}

/**
 * 将输入值转换为数字以进行持久化。
 * 如果转换失败,返回原始字符串。
 */
export function toNumber(val: string): number | string {
  const n = parseFloat(val)
  return isNaN(n) ? val : n
}

/**
 * 创建一个map对象,用于检查值是否存在
 */
export function makeMap(
  str: string,
  expectsLowerCase?: boolean
): (key: string) => true | undefined {
  const map = Object.create(null)
  const list: Array<string> = str.split(',')
  for (let i = 0; i < list.length; i++) {
    map[list[i]] = true
  }
  return expectsLowerCase ? val => map[val.toLowerCase()] : val => map[val]
}

下面是makeMap的两个示例,可以用于检查一些关键字。

/**
 * Check if a tag is a built-in tag.
 */
export const isBuiltInTag = makeMap('slot,component', true)

/**
 * Check if an attribute is a reserved attribute.
 */
export const isReservedAttribute = makeMap('key,ref,slot,slot-scope,is')

5 once

export function once<T extends (...args: any[]) => any>(fn: T): T {
  let called = false
  return function () {
    if (!called) {
      called = true
      fn.apply(this, arguments as any)
    }
  } as any
}

这段代码实现了一个 once 函数,该函数可以用来包装一个函数,使其只能被调用一次。这样,如果你想要一个函数只能被执行一次,你可以使用这个函数来包装原函数。例如:

const myFunction = () => {
  console.log('我只执行一次')
}

const wrappedFunction = once(myFunction)

// 第一次调用会打印出信息
wrappedFunction() // 我只执行一次

// 下面的代码将不会起作用
wrappedFunction()
wrappedFunction()
wrappedFunction()

这段代码提供了一种简单的方法来限制函数的调用次数。这在某些情况下可能非常有用,例如当你想要确保一个函数只会在特定条件下被执行一次时。

总结

学习了部分工具函数的用法,以及他们的原理,大部分代码都很简洁,这也是很多优秀开源项目具备的,通过函数的命名以及注释使读者在不看源代码的情况下就大致了解这个函数的作用是什么,在平常开发过程中,也要时刻要求自己注意这一点。

标签:function,return,val,共读,value,源码,export,vue2,any
From: https://blog.51cto.com/codeniu/6207240

相关文章

  • 知识付费小程序源码资源共享会员积分广告小程序定制开发源码二开
    资源分享可以在后台添加各种资源,如风景,写真,cos,壁纸,各种链接。后台可以设置这些资源如何观看,免费,看广告,VIP广告设置可以添加各种广告,可以在广告设置里设置好广告id还有广告应用场景。VIP设置管理员可以在后台更改用户的VIP设置,也可以设置卡密,让用户自行解锁vip,也可以设置积分,让用户......
  • 降低就医门槛,提高医疗效率,互联网医院源码应用案例分享
    互联网医院系统源码是基于最新的Web技术和云计算技术所构建的一种全新的医疗信息化平台。该平台可以通过网页、移动APP等多种方式,为患者提供在线预约挂号、线上问诊、电子处方、在线支付等一系列便捷、快速、安全的医疗服务。该系统源码的设计理念是以患者为中心,将医院的各个科室、......
  • ConcurrentHashMap源码&底层数据结构分析
    ConcurrentHashMap:线程安全的HashMap1.存储结构 ConcurrnetHashMap由很多个Segment组合,而每一个Segment是一个类似于HashMap的结构,所以每一个HashMap的内部可以进行扩容。但是Segment的个数一旦初始化就不能改变,默认Segment的个数是16个,你也可以认为Concu......
  • 从医疗服务到健康管理:互联网医院系统源码的应用探究
    随着互联网技术的快速发展,互联网医院系统逐渐成为医疗服务的新模式。相较于传统医疗服务,互联网医院系统具有更为便捷、高效、个性化的优势,能够为用户提供更加全面、精细的健康管理服务。本文将探究互联网医院系统源码的应用现状和未来发展方向。一、基本概念互联网医院系统源码,是指......
  • 视频直播系统源码,CSS3如何调整背景图片大小
    视频直播系统源码,CSS3如何调整背景图片大小1.lengthlength:设置背景图片的高度与宽度。第一个值设置宽度,第二个值为高度。如果只给出第一个值,那么第二值则设置为auto(自动)。 举例,将背景图片改为20emx20em(默认1px=.05em)       width:30em;      ......
  • 提高kafka消费速度之从源码去了解Spring-kafka的concurrency参数
    网上看到这篇文章,觉得很不错,这里转载记录一下。转自:提高kafka消费速度之从源码去了解Spring-kafka的concurrency参数-简书第一部分、引言    在spring应用中,如果我们需要订阅kafka消息,通常情况下我们不会直接使用kafka-client,而是使用了更方便的一层封装spring-kafk......
  • springboot项目 宿舍管理系统 (源码+数据库文件+1w字论文+ppt)
    来了就点个赞再走呗,即将毕业的兄弟有福了文章底部获取源码springboot项目宿舍管理系统(源码+数据库文件+1w字论文+ppt)技术框架:java+springboot+vue+mysql后端框架:SpringBoot、SpringMVC、MyBatisPlus前端界面:vue、BootStrap、jQuery、ajxs系统共分为三种用户系统主要功......
  • 【Vue2.x源码系列06】计算属性computed原理
    上一章Vue2异步更新和nextTick原理,我们介绍了JavaScript执行机制是什么?nextTick源码是如何实现的?以及Vue是如何异步更新渲染的?本章目标计算属性是如何实现的?计算属性缓存原理-带有dirty属性的watcher洋葱模型的应用初始化在Vue初始化实例的过程中,如果用户options选......
  • java学习日记20230414-HashSet源码
    HashSetHashSet底层是HashMap添加一个元素时,先得到Hash值,会转化成索引值;找到存储数据表table,看这个索引位置是否存放元素;如果没有直接加入如果有,调用equals比较,如果相同放弃添加,如果不同,则添加到最后在java8中,如果一条链表的元素个数到达TREEIFY_THRESHOLD(默认是8)(table表......
  • 源码共读|yocto-queue 队列 链表
    前言Yocto-queue是一种允许高效存储和检索数据的数据结构。它是一种队列类型,是一个元素集合,其中的项被添加到一端并从另一端移除。它被设计用来操作数据量很大的数组,在你需要使用大量的Array.push、Array.shift操作时,Yocto-queue有更好的性能表现。仓库地址:sindresorhus/yo......