详解Vue源码中一些util函数


Posted in Javascript onApril 24, 2019

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]

详解Vue源码中一些util函数

上图是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函数详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
jQuery EasyUI API 中文文档 - ComboTree组合树
Oct 11 Javascript
jquery 如何动态添加、删除class样式方法介绍
Nov 07 Javascript
AngularJs html compiler详解及示例代码
Sep 01 Javascript
浅谈js中几种实用的跨域方法原理详解
Dec 02 Javascript
angular forEach方法遍历源码解读
Jan 25 Javascript
vuejs2.0实现一个简单的分页示例
Feb 22 Javascript
从零开始学习Node.js系列教程之设置HTTP头的方法示例
Apr 13 Javascript
Vue实现动态响应数据变化
Apr 28 Javascript
jQuery完成表单验证的实例代码(纯代码)
Sep 30 jQuery
vue-自定义组件传值的实例讲解
Sep 18 Javascript
JQuery的加载和选择器用法简单示例
May 13 jQuery
浅谈vue使用axios的回调函数中this不指向vue实例,为undefined
Sep 21 Javascript
vue-cli3 DllPlugin 提取公用库的方法
Apr 24 #Javascript
VUE 实现复制内容到剪贴板的两种方法
Apr 24 #Javascript
详解一个小实例理解js原型和继承
Apr 24 #Javascript
微信小程序实现的一键复制功能示例
Apr 24 #Javascript
如何基于vue-cli3.0构建功能完善的移动端架子
Apr 24 #Javascript
解决vue 单文件组件中样式加载问题
Apr 24 #Javascript
vue router 用户登陆功能的实例代码
Apr 24 #Javascript
You might like
Oracle Faq(Oracle的版本)
2006/10/09 PHP
PHP insert语法详解
2008/06/07 PHP
php生成过去100年下拉列表的方法
2015/07/20 PHP
PHP类的封装与继承详解
2015/09/29 PHP
PHP实现删除多重数组对象属性并重新赋值的方法
2017/06/07 PHP
用JavaScript显示随机图像或引用
2009/04/21 Javascript
jQuery chili图片远处放大插件
2009/11/30 Javascript
jQuery生成asp.net服务器控件的代码
2010/02/04 Javascript
关于window.pageYOffset和document.documentElement.scrollTop
2011/04/05 Javascript
利用javascript打开模态对话框(示例代码)
2014/01/11 Javascript
js利用事件的阻止冒泡实现点击空白模态框的隐藏
2014/01/24 Javascript
JavaScript计算某一天是星期几的方法
2015/08/05 Javascript
javascript中for/in循环及使用技巧
2015/09/01 Javascript
Javascript removeChild()删除节点及删除子节点的方法
2015/12/27 Javascript
Javascript之Number对象介绍
2016/06/07 Javascript
VUE axios发送跨域请求需要注意的问题
2017/07/06 Javascript
vue父子组件的嵌套的示例代码
2017/09/08 Javascript
小程序实现抽奖动画
2020/04/16 Javascript
p5.js临摹动态图形实现方法详解
2019/10/23 Javascript
Vue跨域请求问题解决方案过程解析
2020/08/07 Javascript
[51:36]EG vs VP 2018国际邀请赛淘汰赛BO3 第一场 8.24
2018/08/25 DOTA
Python3实现的字典遍历操作详解
2018/04/18 Python
使用python将大量数据导出到Excel中的小技巧分享
2018/06/14 Python
pygame游戏之旅 创建游戏窗口界面
2018/11/20 Python
python提取具有某种特定字符串的行数据方法
2018/12/11 Python
python实现简单图片物体标注工具
2019/03/18 Python
详解python实现小波变换的一个简单例子
2019/07/18 Python
Jupyter 无法下载文件夹如何实现曲线救国
2020/04/22 Python
美国网上购买眼镜:Eyeconic
2017/07/29 全球购物
澳大利亚制造的蜡烛和扩散器:Glasshouse Fragrances
2018/05/20 全球购物
美国在线乐器和设备商店:Musician’s Friend
2018/07/06 全球购物
Solaris操作系统的线程机制
2015/07/28 面试题
事业单位接收函
2014/01/10 职场文书
市场营销工作计划书
2014/05/06 职场文书
企业爱岗敬业演讲稿
2014/09/04 职场文书
《童年的发现》教学反思
2016/02/18 职场文书