最近在深入研究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){//构建闭包集合mapvarmap=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的原型arr.unshift(6)//打印结果:调用拦截的unshift方法收集依赖。5.继承实现Vue调用Vue.extend实例化组件。Vue.extend是VueComponent的构造器,而VueComponent继承Vue使用的是Object.create,所以在正常开发中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;returnfunction(){if(!called){called=true;fn.apply(this,arguments);}}}7.浅拷贝和简单深拷贝我们可以使用JSON.stringify()来实现,不过vue源码中looseEqual的浅拷贝也写的很有意思。先判断类型再递归调用不难。让我们学习这个想法。functionlooseEqual(a,b){if(a=b){返回真}varyObjectisObjectA=isObject(a);varyObjectisObjectB=isObject(b);Array.isArray(b)if(isArrayA&&thisArrayB){return.length=b.length&&a.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{/*stanbulignorenext*/returnfalse}}catch(e){/*stanbulignorenext*/returnfalse}}elseif(!isObjectA&&!isObjectB){returnString(a)===String(b)}else{returnfalse}}functionisObject(obj){返回obj!==null&&typeofobj==='对象'}