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源码中一些好玩的函数相关推荐

  1. 什么是php的ast结构,什么是AST?Vue源码中AST语法树的解析

    这篇文章给大家介绍的内容是关于什么是AST?Vue源码中AST语法树的解析,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 什么是AST AST是指抽象语法树(abstract syn ...

  2. 基于Vue源码中e2e测试实践

    您好,如果喜欢我的文章,可以关注我的公众号「量子前端」,将不定期关注推送前端好文~ 基于Vue源码中e2e测试实践 前言 技术选型&对Vue的参考 Puppeteer测试流程 在Concis中 ...

  3. Vue源码中的对象相等比较

    Vue源码中的对象比较函数写的极为经典漂亮,在此进行部分注释并添加一个函数类型比较判断,代码如下: function isObject(o) {return typeof o==='object'}f ...

  4. 学习尤雨溪写的 Vue3 源码中的简单工具函数

    大家好,我是若川.最近组织了源码共读活动.每周读 200 行左右的源码.很多第一次读源码的小伙伴都感觉很有收获,感兴趣可以加我微信ruochuan12,拉你进群学习. 初学者也能看懂的 Vue3 源码 ...

  5. vue源码中优秀代码片段(一)

    一.前言 笔者在读Vue源码时, 手记一些源码中优美的代码片段,一起来学习吧 二.代码片段 1. makeMap 检测某值是否在字符串(逗号分隔的字符串)中存在, 运用了柯里化函数和缓存函数 源码鉴赏 ...

  6. vue中rules校验是验证首字符_小白也能秒懂Vue源码中那些精细设计(选项处理)...

    我"崩"不住了,在彭凡同志锲而不舍的催促下这篇文章终于"蛋"生了. 说正经的这篇文章不好写,不好写的原因是我不太擅长写这些类比文,但它还是写出来了. 相信大部分 ...

  7. Vue源码中compiler部分逻辑梳理(内有彩蛋)

    [摘要] Vue compiler部分逻辑梳理 示例代码托管在:http://www.github.com/dashnowords/blogs 一. 简述 compiler模块Vue框架中用于模板编译 ...

  8. vue 二维数组_最近研究Vue源码时我发现的一些好玩函数

    来源 | segmentfault.com/u/chinamasters 作者 | chinamasters 最近在深入研究vue源码,把学习过程中,看到的一些好玩的的函数方法收集起来做分享,希望对大 ...

  9. vue 拷贝 数组_vue源码中值得学习的方法

    最近在深入研究vue源码,把学习过程中,看到的一些好玩的的函数方法收集起来做分享,希望对大家对深入学习js有所帮助.如果大家都能一眼看懂这些函数,说明技术还是不错的哦. 1. 数据类型判断 Objec ...

  10. 「从源码中学习」面试官都不知道的Vue题目答案

    前言 当回答面试官问及的Vue问题,我们除了照本宣科的回答外,其实还可以根据少量的源码来秀一把,来体现出你对Vue的深度了解. 本文会陆续更新,此次涉及以下问题: "new Vue()做了什 ...

最新文章

  1. 【云栖大会】阿里云生态 开启智能“大航海时代”
  2. L1-009 N个数求和(分数运算模板)(34行代码AC)
  3. 深入浅出深度学习(二)分类器
  4. 使用Spring Boot 2.0的Spring Security:保护端点
  5. android tcp socket框架_花了一个星期,我终于把RPC框架整明白了
  6. Java 面试之语言基础
  7. python 100题_python 100题
  8. AtomicStampedReference解决CAS的ABA问题
  9. mysql密码修改无效后,修改方法
  10. uniapp创建电子签名
  11. 工作室流量卡如何做才能不封号?
  12. 大数据简介、Hadoop 起源以及 Google 三大论文介绍
  13. VS2017编写汇编并调用c库函数(msvcrt.lib)
  14. 孩子为什么不能玩抖音精彩回答,共勉
  15. 移动硬盘读不出来的问题
  16. 如何用c语言添加背景图片,如何实现在单文档的窗口背景上贴上图片?
  17. sqlalchemy 踩过的坑
  18. 如何成为一个漏洞赏金猎人
  19. 计算机应用基础在线试题,计算机应用基础试题.DOC
  20. 购物中心智能管理系统该如何选择

热门文章

  1. 安全产品不安全 杀毒软件为网络攻击打开方便之门
  2. 【报告分享】2021大学生消费行为洞察报告-校果研究院(附下载)
  3. 2021年深圳市技术先进型服务企业认定时间标准及材料
  4. 手把手带你学会Odoo OWL组件开发(7):OWL项目实战使用
  5. 启鸿蒙什么意思,幼学启鸿蒙,望子早成龙!大冶成龙子规幼儿园孔子像落成揭幕仪式...
  6. 完全理解 redux(从零实现一个 redux)
  7. 图片格式与RAM需求
  8. Python 安装库 is not a supported wheel on this platform解决办法
  9. 选择升压转换器电感值
  10. DeepFaceLab进阶:H128,DF,SAE模型有何不同?哪个最好?