详解Vue源码中一些util函数

JS中很多开源库都有一个util文件夹,来存放一些常用的函数。这些套路属于那种常用但是不在ES规范中,同时又不足以单独为它发布一个npm模块。所以很多库都会单独写一个工具函数模块。

最进尝试阅读vue源码,看到很多有意思的函数,在这里分享一下。

Object.prototype.toString.call(arg) 和 String(arg) 的区别?

上述两个表达式都是尝试将一个参数转化为字符串,但是还是有区别的。

String(arg) 会尝试调用 arg.toString() 或者 arg.valueOf(), 所以如果arg或者arg的原型重写了这两个方法,Object.prototype.toString.call(arg) 和 String(arg) 的结果就不同

const _toString = Object.prototype.toString
var obj = {}

obj.toString() // [object Object]
_toString.call(obj) // [object Object]

obj.toString = () => '111'

obj.toString() // 111
_toString.call(obj) // [object Object]

/hello/.toString() // /hello/
_toString.call(/hello/) // [object RegExp]

上图是ES2018的截图,我们可以知道Object.prototype.toString的规则,而且有一个规律,Object.prototype.toString的返回值总是 [object + tag + ],如果我们只想要中间的tag,不要两边烦人的补充字符,我们可以

function toRawType (value) {
 return _toString.call(value).slice(8, -1)
}

toRawType(null) // "Null"
toRawType(/sdfsd/) //"RegExp"

虽然看起来挺简单的,但是很难自发的领悟到这种写法,有木有。。

缓存函数计算结果

假如有这样的一个函数

function computed(str) {
 // 假设中间的计算非常耗时
 console.log('2000s have passed')
 return 'a result'
}

我们希望将一些运算结果缓存起来,第二次调用的时候直接读取缓存中的内容,我们可以怎么做呢?

function cached(fn){
 const cache = Object.create(null)
 return function cachedFn (str) {
  if ( !cache[str] ) {
    cache[str] = fn(str)
  }
  return cache[str]
 }
}

var cachedComputed = cached(computed)
cachedComputed('ss')
// 打印2000s have passed
cachedComputed('ss')
// 不再打印

将hello-world风格的转化为helloWorld风格

const camelizeRE = /-(\w)/g
const camelize = cached((str) => {
 return str.replace(camelizeRE, (_, c) => c ? c.toUpperCase() : '')
})

camelize('hello-world')
// "helloWorld"

判断JS运行环境

const inBrowser = typeof window !== 'undefined'

const inWeex = typeof WXEnvironment !== 'undefined' && !!WXEnvironment.platform
const weexPlatform = inWeex && WXEnvironment.platform.toLowerCase()

const UA = inBrowser && window.navigator.userAgent.toLowerCase()

const isIE = UA && /msie|trident/.test(UA)
const isIE9 = UA && UA.indexOf('msie 9.0') > 0
const isEdge = UA && UA.indexOf('edge/') > 0
const isAndroid = (UA && UA.indexOf('android') > 0) || (weexPlatform === 'android')
const isIOS = (UA && /iphone|ipad|ipod|ios/.test(UA)) || (weexPlatform === 'ios')
const isChrome = UA && /chrome\/\d+/.test(UA) && !isEdge
const isPhantomJS = UA && /phantomjs/.test(UA)
const isFF = UA && UA.match(/firefox\/(\d+)/)

判断一个函数是宿主环境提供的还是用户自定义的

console.log.toString()
// "function log() { [native code] }"

function fn(){}
fn.toString()
// "function fn(){}"

// 所以
function isNative (Ctor){
 return typeof Ctor === 'function' && /native code/.test(Ctor.toString())
}

以上所述是小编给大家介绍的Vue源码中一些util函数详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • 详解在vue-test-utils中mock全局对象

    vue-test-utils   提供了一种 mock 掉   Vue.prototype   的简单方式,不但对测试用例适用,也可以为所有测试设置默认的 mock. mocks   加载选项 mocks   加载选项   是一种将任何属性附加到   Vue.prototype   上的方式.这通常包括: $store , for Vuex $router , for Vue Router $t , for vue-i18n 以及其他种种. vue-i18n   的例子 我们来看一个 vue-i

  • vue-cli脚手架build目录下utils.js工具配置文件详解

    此文章用来解释vue-cli脚手架build目录中的utils.js配置文件 1.此配置文件是vue开发环境的wepack相关配置文件,主要用来处理css-loader和vue-style-loader 2.关于注释 •当涉及到较复杂的解释我将通过标识的方式(如(1))将解释写到单独的注释模块,请自行查看 3.上代码 // 引入nodejs路径模块 var path = require('path') // 引入config目录下的index.js配置文件 var config = requir

  • vue使用xe-utils函数库的具体方法

    本文介绍了vue使用xe-utils函数库的具体方法,分享给大家,具体如下: 安装完成后自动挂载在vue实例:this.$utils(函数库) 支持挂载函数列表:this.$browse(浏览器内核判断) this.$locat(用于读写地址栏参数) 在 vue 实例中通过 this.$utils 调用的函数 this 默认指向当前vue实例. CDN 安装 使用 script 方式安装,VXEUtils 会定义为全局变量 生产环境请使用 vxe-utils.min.js,更小的压缩版本,可以带

  • 详解Vue源码中一些util函数

    JS中很多开源库都有一个util文件夹,来存放一些常用的函数.这些套路属于那种常用但是不在ES规范中,同时又不足以单独为它发布一个npm模块.所以很多库都会单独写一个工具函数模块. 最进尝试阅读vue源码,看到很多有意思的函数,在这里分享一下. Object.prototype.toString.call(arg) 和 String(arg) 的区别? 上述两个表达式都是尝试将一个参数转化为字符串,但是还是有区别的. String(arg) 会尝试调用 arg.toString() 或者 arg

  • 详解Vue源码学习之双向绑定

    原理 当你把一个普通的 JavaScript 对象传给 Vue 实例的 data 选项,Vue 将遍历此对象所有的属性,并使用 Object.defineProperty 把这些属性全部转为 getter/setter.Object.defineProperty 是 ES5 中一个无法 shim 的特性,这也就是为什么 Vue 不支持 IE8 以及更低版本浏览器. 上面那段话是Vue官方文档中截取的,可以看到是使用Object.defineProperty实现对数据改变的监听.Vue主要使用了观

  • 详解Vue源码之数据的代理访问

    概念解析: 1) 数据代理: 通过一个对象代理对另一个对象(在前一个对象内部)中属性的操作(读/写) 2) vue 数据代理: 通过 vm 对象(即this)来代理 data 对象中所有属性的操作 3) 好处: 更方便的操作 data 中的数据 4) 基本实现流程 a. 通过 Object.defineProperty()给 vm 添加与 data 对象的属性对应的属性描述符 b. 所有添加的属性都包含 getter/setter c. getter/setter 内部去操作 data 中对应的

  • 详解Vue源码学习之callHook钩子函数

    Vue实例在不同的生命周期阶段,都调用了callHook方法.比如在实例初始化(_init)的时候调用callHook(vm, 'beforeCreate')和callHook(vm, 'created'). 这里的"beforeCreate","created"状态并非随意定义,而是来自于Vue内部的定义的生命周期钩子. var LIFECYCLE_HOOKS = [ 'beforeCreate', 'created', 'beforeMount', 'mount

  • Android中图片压缩方案详解及源码下载

    Android中图片压缩方案详解及源码下载 图片的展示可以说在我们任何一个应用中都避免不了,可是大量的图片就会出现很多的问题,比如加载大图片或者多图时的OOM问题,可以移步到Android高效加载大图及多图避免程序OOM.还有一个问题就是图片的上传下载问题,往往我们都喜欢图片既清楚又占的内存小,也就是尽可能少的耗费我们的流量,这就是我今天所要讲述的问题:图片的压缩方案的详解. 1.质量压缩法 设置bitmap options属性,降低图片的质量,像素不会减少 第一个参数为需要压缩的bitmap图

  • javascript ES6中set集合、map集合使用方法详解与源码实例

    set与map理解 ES6中新增,set集合和map集合就是一种数据的存储结构(在ES6之前数据存储结构只有array,object),不同的场景使用不同的集合去存储数据 set集合 Set 对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用. set集合语法: //创建一个set集合,传参为一个可迭代的对象 const s1 = new Set(iterable); API 名称 类型 简介 Set.add() 原型方法 添加数据 Set.has() 原型方法 判断是否存在一个数据 S

  • Vue源码中要const _toStr = Object.prototype.toString的原因分析

    在vue的源码中,vue/src/shared/util.js文件中存放的是一些方法.其中作者用了Object.prototype.toString这个方法来判断类型,但是并没有直接用,而是单独保存在一个变量: const _toStr = Object.prototype.toString 那么为什么要这么做呢? 先说下判断类型.众所周知,typeof在判断对象时不能正确判断Null,并且不能识别出Array,但在判断基础类型时是没问题的.所以尤大也写了: export function is

  • Oracle 错误日志表及异常处理包详解 附源码

    1 概述 1. 目的:'快速定位程序异常' 2. 包处理的核心思想:'自治事务' -- 自治事务的 "提交.回滚" 与 主事务 之间互不影响 3. 错误异常记录逻辑大体一致,此处记录,方便需要使用时复制.粘贴 4. 验证思路:通过执行报错的过程,观察 '程序执行结果' 和 '日志表' 数据插入情况 2 效果演示 程序执行截图: 日志表查询截图: 3 源码 说明: 1. 测试中,共有 2 个用户 -- 模拟实际开发场景 (1) odsdata: 存放业务数据 (2) odscde : 执

  • 详解从源码分析tomcat如何调用Servlet的初始化

    引言 上一篇博客我们将tomcat源码在本地成功运行了,所以在本篇博客中我们从源码层面分析,tomcat在启动的过程中,是如何初始化servlet容器的.我们平常都是将我们的服务部署到 tomcat中,然后修改一下配置文件,启动就可以对外提供 服务了,但是我们对于其中的一些流程并不是非常的了解,例如如何加载的web.xml等.这是我们分析servlet 和 sringMVC必不可少的过程. 注释源码地址:https://github.com/good-jack/tomcat_source/tre

  • Java SpringBoot自动装配原理详解及源码注释

    目录 一.pom.xml文件 1.父依赖 2.启动器: 二.主程序: 剖析源码注解: 三.结论: 一.pom.xml文件 1.父依赖 主要是依赖一个父项目,管理项目的资源过滤以及插件! 资源过滤已经配置好了,无需再自己配置 在pom.xml中有个父依赖:spring-boot-dependencies是SpringBoot的版本控制中心! 因为有这些版本仓库,我们在写或者引入一些springboot依赖的时候,不需要指定版本! 2.启动器: 启动器也就是Springboot的启动场景; 比如sp

随机推荐