最近一直在深入研究vue源码,把学习过程中看到的一些有趣的功能和方法收集起来分享给大家。希望对大家深入学习js有所帮助。如果大家一眼就能看懂这些功能,说明技术还是不错的。1.确定数据类型。Object.prototype.toString.call()返回的数据格式为[objectObject]类型,然后用slice截取第8位到最后一位,结果为Objectvar_toString=Object.prototype.toString;functiontoRawType(value){return_toString.call(value).slice(8,-1)}运行结果测试toRawType({})//ObjecttoRawType([])//ArraytoRawType(true)//BooleantoRawType(undefined)//UndefinedtoRawType(null)//NulltoRawType(function(){})//Function2。在Vue中使用闭包构造地图缓存数据来判断我们写的组件名是否是内置的HTML标签。如果使用数组类来遍历,会循环很多次才能得到结果。如果将数组转化为对象,将标签名设置为对象的key,那么就不需要一个一个遍历查找,只需要查找一次就可以得到结果,提高了查找效率.functionmakeMap(str,expectsLowerCase){//构建闭包集合映射varmap=Object.create(null);varlist=str.split(',');for(vari=0;i{array_methods[method]=function(){//拦截方法console.log('拦截'+method+'方法被调用,进行依赖收集');returnArray.prototype[method].apply(this,arguments);}});运行结果测试vararr=[1,2,3]arr.__proto__=array_methods//改变arr的原型。unshift(6)//打印结果:调用截获的unshift方法收集依赖5.继承的实现调用Vue中的Vue.extend实例化组件。Vue.extend是VueComponent的构造器,而VueComponent继承自Object.createVue,所以正常开发中Vue和Vue.extend没有太大区别。这里主要学习使用es5的native方法来实现继承。当然,es6中的类class是extends直接继承的。//继承方法functioninheritPrototype(Son,Father){varprototype=Object.create(Father.prototype)prototype.constructor=Son//将Father.prototype赋给Son.prototypeSon.prototype=prototype}functionFather(name){this.name=namethis.arr=[1,2,3]}Father.prototype.getName=function(){console.log(this.name)}functionSon(name,age){Father.call(this,name)this.age=age}inheritPrototype(Son,Father)Son.prototype.getAge=function(){console.log(this.age)}运行结果测试varson1=newSon("AAA",23)son1。getName()//AAAson1.getAge()//23son1.arr.push(4)console.log(son1.arr)//1,2,3,4varson2=newSon("BBB",24)son2.getName()//BBBson2.getAge()//24console.log(son2.arr)//1,2,36。执行once方法比较简单,直接用闭包实现functiononce(fn){varcalled=false;返回函数(){if(!called){called=true;fn.apply(这个,参数s);}}}7.对象判断vue源码中的looseEqual判断两个对象是否相等,先判断类型再递归调用,总体不难,学习思路functionlooseEqual(a,b){if(a===b){返回真}varisObjectA=isObject(a);varisObjectB=isObject(b);如果(isObjectA&&isObjectB){try{varisArrayA=Array。是数组(一);varisArrayB=Array.isArray(b);如果(isArrayA&&isArrayB){返回一个。长度===b。长度&&一个。every(function(e,i){returnlooseEqual(e,b[i])})}elseif(!isArrayA&&!isArrayB){varkeysA=Object.keys(a);varkeysB=Object.keys(b);returnkeysA.length===keysB.length&&keysA.every(function(key){returnlooseEqual(a[key],b[key])})}else{/*istanbulignorenext*/returnfalse}}catch(e){/*忽略下一个*/returnfalse}}elseif(!isObjectA&&!isObjectB){returnString(a)===String(b)}else{returnfalse}}functionisObject(obj){;返回对象!==null&&typeofobj==='object'}基于以上思路,我自己写了一个深拷贝的方法,但是我们可以使用JSON.stringify()来实现一个简单的深拷贝。functiondeepClone(source){if(!source&&typeofsource!=='object'){thrownewError('errorarguments','deepClone')}consttargetObj=source.constructor===数组?[]:{}Object.keys(source).forEach(keys=>{if(source[keys]&&typeofsource[keys]==='object'){targetObj[keys]=deepClone(source[keys])}else{targetObj[keys]=source[keys]}})returntargetObj}先分享这些功能,其他的功能会在后面补充。如有不妥之处,请指正,谢谢!