Vue源码中一些好玩的函数
1、数据类型判断
Object.prototype.toString.call()返回的数据格式为 [object Object]类型,然后用slice截取第8位到倒一位,得到结果为 Object
var _toString = Object.prototype.toString;
function toRawType (value) {return _toString.call(value).slice(8, -1)
}
运行结果测试
toRawType({}) // Object
toRawType([]) // Array
toRawType(true) // Boolean
toRawType(undefined) // Undefined
toRawType(null) // Null
toRawType(function(){}) // Function
2、利用闭包构造map缓存数据
vue中判断我们写的组件名是不是html内置标签的时候,如果用数组类遍历那么将要循环很多次获取结果,如果把数组转为对象,把标签名设置为对象的key,那么不用依次遍历查找,只需要查找一次就能获取结果,提高了查找效率。
function makeMap (str, expectsLowerCase) {// 构建闭包集合mapvar map = Object.create(null);var list = str.split(',');for (var i = 0; i < list.length; i++) {map[list[i]] = true;}return expectsLowerCase? function (val) { return map[val.toLowerCase()]; }: function (val) { return map[val]; }
}
// 利用闭包,每次判断是否是内置标签只需调用isHTMLTag
var isHTMLTag = makeMap('html,body,base,head,link,meta,style,title')
console.log('res', isHTMLTag('body')) // true
3、二维数组扁平化
vue中_createElement格式化传入的children的时候用到了simpleNormalizeChildren函数,原来是为了拍平数组,使二维数组扁平化,类似lodash中的flatten方法。
// 先看lodash中的flatten
_.flatten([1, [2, [3, [4]], 5]])
// 得到结果为 [1, 2, [3, [4]], 5]// vue中
function simpleNormalizeChildren (children) {for (var i = 0; i < children.length; i++) {if (Array.isArray(children[i])) {return Array.prototype.concat.apply([], children)}}return children
}// es6中 等价于
function simpleNormalizeChildren (children) {return [].concat(...children)
}
4、方法拦截
vue中利用Object.defineProperty收集依赖,从而触发更新视图,但是数组却无法监测到数据的变化,但是为什么数组在使用push pop等方法的时候可以触发页面更新呢,那是因为vue内部拦截了这些方法。
// 重写push等方法,然后再把原型指回原方法var ARRAY_METHOD = [ 'push', 'pop', 'shift', 'unshift', 'reverse', 'sort', 'splice' ];var array_methods = Object.create(Array.prototype);ARRAY_METHOD.forEach(method => {array_methods[method] = function () {// 拦截方法console.log('调用的是拦截的 ' + method + ' 方法,进行依赖收集');return Array.prototype[method].apply(this, arguments);}});
运行结果测试
var arr = [1,2,3]
arr.__proto__ = array_methods // 改变arr的原型
arr.unshift(6) // 打印结果: 调用的是拦截的 unshift 方法,进行依赖收集
5、继承的实现
vue中调用Vue.extend实例化组件,Vue.extend就是VueComponent构造函数,而VueComponent利用Object.create继承Vue,所以在平常开发中Vue 和 Vue.extend区别不是很大。这边主要学习用es5原生方法实现继承的,当然了,es6中 class类直接用extends继承。
// 继承方法 function inheritPrototype(Son, Father) {var prototype = Object.create(Father.prototype)prototype.constructor = Son// 把Father.prototype赋值给 Son.prototypeSon.prototype = prototype}function Father(name) {this.name = namethis.arr = [1,2,3]}Father.prototype.getName = function() {console.log(this.name)}function Son(name, age) {Father.call(this, name)this.age = age}inheritPrototype(Son, Father)Son.prototype.getAge = function() {console.log(this.age)}
运行结果测试
var son1 = new Son("AAA", 23)
son1.getName() //AAA
son1.getAge() //23
son1.arr.push(4)
console.log(son1.arr) //1,2,3,4var son2 = new Son("BBB", 24)
son2.getName() //BBB
son2.getAge() //24
console.log(son2.arr) //1,2,3
6. 执行一次
once 方法相对比较简单,直接利用闭包实现就好了
function once (fn) {var called = false;return function () {if (!called) {called = true;fn.apply(this, arguments);}}
}
7、浅拷贝
简单的深拷贝我们可以用 JSON.stringify() 来实现,不过vue源码中的looseEqual 浅拷贝写的也很有意思,先类型判断再递归调用,总体也不难,学一下思路。
function looseEqual (a, b) {if (a === b) { return true }var isObjectA = isObject(a);var isObjectB = isObject(b);if (isObjectA && isObjectB) {try {var isArrayA = Array.isArray(a);var isArrayB = Array.isArray(b);if (isArrayA && isArrayB) {return a.length === b.length && a.every(function (e, i) {return looseEqual(e, b[i])})} else if (!isArrayA && !isArrayB) {var keysA = Object.keys(a);var keysB = Object.keys(b);return keysA.length === keysB.length && keysA.every(function (key) {return looseEqual(a[key], b[key])})} else {/* istanbul ignore next */return false}} catch (e) {/* istanbul ignore next */return false}} else if (!isObjectA && !isObjectB) {return String(a) === String(b)} else {return false}
}
function isObject (obj) {return obj !== null && typeof obj === 'object'
}
就先分享这些函数,其他函数,后面继续补充,如有不对欢迎指正,谢谢!
Vue源码中一些好玩的函数相关推荐
- 什么是php的ast结构,什么是AST?Vue源码中AST语法树的解析
这篇文章给大家介绍的内容是关于什么是AST?Vue源码中AST语法树的解析,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 什么是AST AST是指抽象语法树(abstract syn ...
- 基于Vue源码中e2e测试实践
您好,如果喜欢我的文章,可以关注我的公众号「量子前端」,将不定期关注推送前端好文~ 基于Vue源码中e2e测试实践 前言 技术选型&对Vue的参考 Puppeteer测试流程 在Concis中 ...
- Vue源码中的对象相等比较
Vue源码中的对象比较函数写的极为经典漂亮,在此进行部分注释并添加一个函数类型比较判断,代码如下: function isObject(o) {return typeof o==='object'}f ...
- 学习尤雨溪写的 Vue3 源码中的简单工具函数
大家好,我是若川.最近组织了源码共读活动.每周读 200 行左右的源码.很多第一次读源码的小伙伴都感觉很有收获,感兴趣可以加我微信ruochuan12,拉你进群学习. 初学者也能看懂的 Vue3 源码 ...
- vue源码中优秀代码片段(一)
一.前言 笔者在读Vue源码时, 手记一些源码中优美的代码片段,一起来学习吧 二.代码片段 1. makeMap 检测某值是否在字符串(逗号分隔的字符串)中存在, 运用了柯里化函数和缓存函数 源码鉴赏 ...
- vue中rules校验是验证首字符_小白也能秒懂Vue源码中那些精细设计(选项处理)...
我"崩"不住了,在彭凡同志锲而不舍的催促下这篇文章终于"蛋"生了. 说正经的这篇文章不好写,不好写的原因是我不太擅长写这些类比文,但它还是写出来了. 相信大部分 ...
- Vue源码中compiler部分逻辑梳理(内有彩蛋)
[摘要] Vue compiler部分逻辑梳理 示例代码托管在:http://www.github.com/dashnowords/blogs 一. 简述 compiler模块Vue框架中用于模板编译 ...
- vue 二维数组_最近研究Vue源码时我发现的一些好玩函数
来源 | segmentfault.com/u/chinamasters 作者 | chinamasters 最近在深入研究vue源码,把学习过程中,看到的一些好玩的的函数方法收集起来做分享,希望对大 ...
- vue 拷贝 数组_vue源码中值得学习的方法
最近在深入研究vue源码,把学习过程中,看到的一些好玩的的函数方法收集起来做分享,希望对大家对深入学习js有所帮助.如果大家都能一眼看懂这些函数,说明技术还是不错的哦. 1. 数据类型判断 Objec ...
- 「从源码中学习」面试官都不知道的Vue题目答案
前言 当回答面试官问及的Vue问题,我们除了照本宣科的回答外,其实还可以根据少量的源码来秀一把,来体现出你对Vue的深度了解. 本文会陆续更新,此次涉及以下问题: "new Vue()做了什 ...
最新文章
- 【云栖大会】阿里云生态 开启智能“大航海时代”
- L1-009 N个数求和(分数运算模板)(34行代码AC)
- 深入浅出深度学习(二)分类器
- 使用Spring Boot 2.0的Spring Security:保护端点
- android tcp socket框架_花了一个星期,我终于把RPC框架整明白了
- Java 面试之语言基础
- python 100题_python 100题
- AtomicStampedReference解决CAS的ABA问题
- mysql密码修改无效后,修改方法
- uniapp创建电子签名
- 工作室流量卡如何做才能不封号?
- 大数据简介、Hadoop 起源以及 Google 三大论文介绍
- VS2017编写汇编并调用c库函数(msvcrt.lib)
- 孩子为什么不能玩抖音精彩回答,共勉
- 移动硬盘读不出来的问题
- 如何用c语言添加背景图片,如何实现在单文档的窗口背景上贴上图片?
- sqlalchemy 踩过的坑
- 如何成为一个漏洞赏金猎人
- 计算机应用基础在线试题,计算机应用基础试题.DOC
- 购物中心智能管理系统该如何选择
热门文章
- 安全产品不安全 杀毒软件为网络攻击打开方便之门
- 【报告分享】2021大学生消费行为洞察报告-校果研究院(附下载)
- 2021年深圳市技术先进型服务企业认定时间标准及材料
- 手把手带你学会Odoo OWL组件开发(7):OWL项目实战使用
- 启鸿蒙什么意思,幼学启鸿蒙,望子早成龙!大冶成龙子规幼儿园孔子像落成揭幕仪式...
- 完全理解 redux(从零实现一个 redux)
- 图片格式与RAM需求
- Python 安装库 is not a supported wheel on this platform解决办法
- 选择升压转换器电感值
- DeepFaceLab进阶:H128,DF,SAE模型有何不同?哪个最好?