「从源码中学习」Vue源码中的JS骚操作
栏目: JavaScript · 发布时间: 5年前
内容简介:解析:使用正则去匹配 UA 中是否包含来源:
// 通过判断 `window` 对象是否存在即可 export const inBrowser = typeof window !== 'undefined' 复制代码
1.2 hasProto
:检查当前环境是否可以使用对象的 __proto__
属性
// 一个对象的 __proto__ 属性指向了其构造函数的原型 // 从一个空的对象字面量开始沿着原型链逐级检查。 export const hasProto = '__proto__' in {} 复制代码
2. user Agent
常量的一系列操作
2.1 获取当浏览器的 user Agent
// toLowerCase目的是 为了后续的各种环境检测 export const UA = inBrowser && window.navigator.userAgent.toLowerCase() 复制代码
2.2 IE浏览器判断
export const isIE = UA && /msie|trident/.test(UA)
解析:使用正则去匹配 UA 中是否包含 'msie'
或者 'trident'
这两个字符串即可判断是否为 IE 浏览器
来源: Internet Explorer User Agent Strings
多关键词高亮插件:Multi-highlight
2.3 IE9
| Edge
| Chrome
判断
export const isIE9 = UA && UA.indexOf('msie 9.0') > 0 export const isEdge = UA && UA.indexOf('edge/') > 0 export const isChrome = UA && /chrome\/\d+/.test(UA) && !isEdge 复制代码
3. 字符串操作
3.1 isReserved
:检测字符串是否以 $ 或者 _ 开头
// charCodeAt() 方法可返回指定位置的字符的 Unicode 编码 export function isReserved (str: string): boolean { const c = (str + '').charCodeAt(0) return c === 0x24 || c === 0x5F } 复制代码
解析:获得该字符串第一个字符的 unicode
,然后与 0x24
和 0x5F
作比较。
若作为一个想进阶中高级的前端, charCodeAt
方法的各种妙用还是需要知道的(面试算法题各种考)。
3.2 camelize
: 连字符转驼峰
const camelizeRE = /-(\w)/g export const camelize = cached((str: string): string => { return str.replace(camelizeRE, (_, c) => c ? c.toUpperCase() : '') }) 复制代码
解析:定义正则表达式: /-(\w)/g
,用来全局匹配字符串中 中横线及连字符后的一个字符。若捕获到,则将字符以 toUpperCase
大写替换,否则以 ''
替换。 如: camelize('aa-bb') // aaBb
3.3 toString
: 将给定变量的值转换为 string 类型并返回
export function toString (val: any): string { return val == null ? '' : typeof val === 'object' ? JSON.stringify(val, null, 2) : String(val) } 复制代码
解析:在 Vue
中充斥着很多这类增强型的封装,大大减少了我们代码的复杂性。但这里,我们要学习的是这种 多重三元运算符
的用法
3.3.1 多重三元运算符
export function toString (val: any): string { return val == null ? '' : typeof val === 'object' ? JSON.stringify(val, null, 2) : String(val) } 复制代码
解析:
export function toString (val: any): string { return 当变量值为 null 时 ? 返回空字符串 : 否则,判断当变量类型为 object时 ? 返回 JSON.stringify(val, null, 2) : 否则 String(val) } 复制代码
3.4 capitalize
:首字符大写
// 忽略cached export const capitalize = cached((str: string): string => { return str.charAt(0).toUpperCase() + str.slice(1) }) 复制代码
解析: str.charAt(0)
获取 str
的第一项,利用 toUpperCase()
转换为大写字母, str.slice(1)
截取除第一项的 str
部分。
4. 类型判断
4.1 isPrimitive
: 判断变量是否为原型类型
export function isPrimitive (value: any): boolean %checks { return ( typeof value === 'string' || typeof value === 'number' || // $flow-disable-line typeof value === 'symbol' || typeof value === 'boolean' ) } 复制代码
解析:这个很简单,但我们经常忽略掉 symbol
这个类型(虽然完全没用过)。
4.2 isRegExp
: 判断变量是否为正则对象。
// 使用 Object.prototype.toString 与 '[object RegExp]' 做全等对比。 export function isRegExp (v: any): boolean { return _toString.call(v) === '[object RegExp]' } 复制代码
这也是最准确的类型判断方法,在 Vue
中其它类型也是一样的判断
4.3 isValidArrayIndex
: 判断变量是否含有效的数组索引
export function isValidArrayIndex (val: any): boolean { const n = parseFloat(String(val)) // n >= 0 && Math.floor(n) === n 保证了索引是一个大于等于 0 的整数 return n >= 0 && Math.floor(n) === n && isFinite(val) } 复制代码
isFinite
方法检测它参数的数值。如果参数是 NaN
,正无穷大或者负无穷大,会返回 false
,其他返回 true
。
扩展:语法:isFinite()
5.Vue中的闭包骚操作
5.1 makeMap()
:判断一个变量是否包含在传入字符串里
export function makeMap ( str: string, expectsLowerCase?: boolean ): (key: string) => true | void { 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] } 复制代码
- 定义一个对象
map
- 将
str
分隔成数组并保存到list
变量中 - 遍历
list
,并以list
中的元素作为map
的key
,将其设置为true
- 返回一个函数,并且如果
expectsLowerCase
为true
的话,小写map[key]
:
我们用一个例子来说明下:
let isMyName = makMap('前端劝退师,帅比',true); //设定一个检测是否为我的名字的方法,第二个参数不区分大小写 isMyName('前端劝退师') // true isMyName('帅比') // true isMyName('丑逼') // false 复制代码
Vue
中类似的判断非常多,也很实用。
5.1.1 isHTMLTag
| isSVG
| isReservedAttr
这三个函数是通过 makeMap
生成的,用来检测一个属性(标签)是否为保留属性(标签)
export const isHTMLTag = makeMap( 'html,body,base,head,link,meta,style,title,' + 'address,article,aside,footer,header,h1,h2,h3,h4,h5,h6,hgroup,nav,section,' + 'div,dd,dl,dt,figcaption,figure,picture,hr,img,li,main,ol,p,pre,ul,' + 'a,b,abbr,bdi,bdo,br,cite,code,data,dfn,em,i,kbd,mark,q,rp,rt,rtc,ruby,' + 's,samp,small,span,strong,sub,sup,time,u,var,wbr,area,audio,map,track,video,' + 'embed,object,param,source,canvas,script,noscript,del,ins,' + 'caption,col,colgroup,table,thead,tbody,td,th,tr,' + 'button,datalist,fieldset,form,input,label,legend,meter,optgroup,option,' + 'output,progress,select,textarea,' + 'details,dialog,menu,menuitem,summary,' + 'content,element,shadow,template,blockquote,iframe,tfoot' ) export const isSVG = makeMap( 'svg,animate,circle,clippath,cursor,defs,desc,ellipse,filter,font-face,' + 'foreignObject,g,glyph,image,line,marker,mask,missing-glyph,path,pattern,' + 'polygon,polyline,rect,switch,symbol,text,textpath,tspan,use,view', true ) // web平台的保留属性有 style 和 class export const isReservedAttr = makeMap('style,class') 复制代码
5.2 once
:只调用一次的函数
export function once (fn: Function): Function { let called = false return function () { if (!called) { called = true fn.apply(this, arguments) } } } 复制代码
解析:以 called
作为回调标识符。调用此函数时, called
标示符改变,下次调用就无效了。也是典型的闭包调用。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- jQuery源码学习:异步操作--Callbacks
- B 站源码泄露?这是—什么—操作(黑人问号)?
- Kylin页面System操作源码解读 原 荐
- Flink 源码阅读笔记(十三):双流操作的实现
- RxJava2源码分析(二):操作符原理分析
- Laravel Database——数据库的 CRUD 操作源码分析
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
High-Performance Compilers for Parallel Computing
Michael Wolfe / Addison-Wesley / 1995-6-16 / USD 117.40
By the author of the classic 1989 monograph, Optimizing Supercompilers for Supercomputers, this book covers the knowledge and skills necessary to build a competitive, advanced compiler for parallel or......一起来看看 《High-Performance Compilers for Parallel Computing》 这本书的介绍吧!