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

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,所以在平常开发中VueVue.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'
}

就先分享这些函数,其他函数,后面继续补充,如有不对欢迎指正,谢谢!

作者:chinamasters
链接:https://segmentfault.com/a/1190000025157159
来源:segmentfault
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

vue 拷贝 数组_vue源码中值得学习的方法相关推荐

  1. Python:如何查看一个对象有哪些属性、方法以及查询源码中只有pass的方法的参数

    Python:如何查看一个对象有哪些属性.方法以及查询源码中只有pass的方法的参数 1.问题背景 2.解决思路 2.1.查看对象有哪些属性或方法 2.1.1.dir()函数 2.1.2.help命令 ...

  2. WebRTC源码中turnserver的使用方法

    WebRTC的源码中自带了一个turnserver,编译之后,会在out/Default下生成一个turnserver文件,可以充当STUN和TURN server.用法如下: ./turnserve ...

  3. android 静态工厂方法,Android 源码中的静态工厂方法

    我们知道工厂模式有三兄弟,通常我们说的工厂模式指的是工厂方法模式,它的应用频率最高.本篇博客分享的简单工厂模式是工厂方法模式的"小弟",确切的来讲它不属于设计模式,而是一种方法.此 ...

  4. vue foreach用法_vue 源码探究(第二弹)

    vue 源码探究(第二弹) 接着上一篇,继续来讲一个非常有意思的东西documentFragment 解析 六.DocumentFragment: 文档碎片(高效批量更新多个节点) 这里先甩出 2 个 ...

  5. Vue 合同模板_vue源码逐行注释分析+40多m的vue源码程序流程图思维导图

    vue源码业余时间差不多看了一年,以前在网上找帖子,发现很多帖子很零散,都是一部分一部分说,断章的很多,所以自己下定决定一行行看,经过自己坚持与努力,现在基本看完了,差ddf那部分,因为考虑到自己要换 ...

  6. 从Mybatis源码中,学习到的10种设计模式

    一.前言:小镇卷码家 总有不少研发伙伴问小傅哥:"为什么学设计模式.看框架源码.补技术知识,就一个普通的业务项目,会造飞机不也是天天写CRUD吗?" 你说的没错,但你天天写CRUD ...

  7. Google 源码中电池百分比获取方法和格式转换

    Google 源码的电池百分比获取和转换 package com.android.settingslib;public class Utils {/** Formats a double from 0 ...

  8. vue 拷贝 数组_vue 使用lodash实现对象数组深拷贝操作

    我就废话不多说了,大家还是直接看代码吧~ export default { mounted() { this.init(); }, methods: { init() { let lodash = r ...

  9. vue 拷贝 数组_Vue实现对数组、对象的深拷贝、复制

    浅拷贝:复制引用地址 : 深拷贝:复制对象 方法一 JSON.parse(JSON.stringify()) 示例: computed: { data: function () { var obj={ ...

最新文章

  1. delphi与java 类型转换_java中的数据类型转换
  2. useradd -g mysql mysql_Linux —— useradd -g mysql mysql解析及useradd详解
  3. 开发技巧-使用SQL与Navicat快速导出一个自定义的MYSQL数据库字段表格(数据字典)为Word或Excel
  4. 正确使用和理解C#中的闭包
  5. silverlight 自定义资源整理(待后续补充)
  6. Java集合框架源码解读(3)——LinkedHashMap
  7. [雪峰磁针石博客]软件测试专家工具包2性能测试
  8. finereport自带的模板目录
  9. Qt 动态加载.qrc文件
  10. DELL服务器硬件报错及对应的解决方法(R710)
  11. php加速模块cpan模块,查看perl模块和cpan模块介绍
  12. Python 课程学习笔记(5)列表 [ ] lst
  13. 10 个 jQuery 的360 度图片展示插件
  14. PostgreSQL 源码解读(216)- 实现简单的扩展函数
  15. RJ45和PSY之间为什么用网络变压器
  16. nikebot nike机器人 如何做一个nikebot nike监控怎么能不延迟 nike如何过盾 bot 机器人 snkrs
  17. 【考研计算机组成原理】课堂笔记目录汇总——知识点清晰
  18. Java实现多图片和文字编辑成一张图片
  19. Google code android开源项目
  20. 年度十大金融投资书籍

热门文章

  1. js 报错:object is not a function
  2. Java判断隐藏文件
  3. ajax提交表单序列化(serialize())数据
  4. Linux中的三个特殊文件
  5. git拉取远程分支到本地分支或者创建本地新分支
  6. 连接服务器用xshell还是linux,【linux☞5】xshell 连接服务器的简单介绍
  7. active mq topic消费后删除_RabbitMQ重复消费,顺序消费,消息丢失如何解决
  8. npm install -g cnpm --registry=https://registry.npm.taobao.org报警告
  9. 创建loop15设备挂载镜像文件(.img)
  10. 高通平台手机开发之Bring-up