那些熟悉但不是很熟悉的知识
时间:2023-04-03 00:29:10
HTML
本文是知识的集合,这些东西在工作中可能用的不多,但总有人想让你知道前言:小时候,我渴望长大了,羡慕成年人的财富和自由;长大后,我羡慕我的童年,怀念我无忧无虑的童年,等待那份纯真。哦,还有,你长大后不会变得富有和自由。..1:js继承①:对象伪装实现继承:(可以实现多重继承)——原理:让父类的构造函数成为子类的方法,然后调用子类的方法,给所有属性赋值和方法通过this关键字functionParent(name){this.name=name;this.sayName=function(){console.log(this.name);}}functionChild(cname){this.parent=Parent;this.parent(cname);删除this.parent;//删除无用的父函数==fParent(name)}varmychild=newChild("name");mychild.sayName();②:原型链继承(不能实现多重继承)原型函数Parent(name,年龄){this.name=名字;这个。年龄=年龄;this.ParFunc=function(){console.log(this.height)}};Parent.prototype.sayName=function(){console.log(this)};functionChild(cname,cage,height){this.height=height}Child.prototype=newParent();//子原型指向父类的一个实例Child.prototype.constructor=Child;//把Child指向自己,不与Parent共享varchild=newChild('TestName','TestAge','TestHeight')console.log(child)//发现打印的属性是全部继承,就是没有价值的child.ParFunc():访问ParFunc属性时,会先在child的instance属性中查找,如果找不到,再去child的原型对象中查找。逐层查找构成原型链,因为无法给父类构造函数传递参数;此时可以使用newParent('name','age')传递引用注意:如果要使用原型扩展Child的方法:Child.prototype.childHeight=function(){console.log(this.height)}一定要写在Child.prototype=newParent()下面,否则会被覆盖。③:调用,应用继承(不能继承原型链,在原型上)functionParent(name,age){this.name=name;这个。年龄=年龄;this.ParFunc=function(){console.log(this.name)}}functionChild(cname,cage,height){Parent.call(this,cname,cage);//继承的参数是当前函数的形参//apply:Parent.call(this,arguments);这个。高度=高度;}varchild=newChild('测试姓名','测试年龄','测试身高')console.log(child)//ParFunc:?()age:"测试年龄"name:"测试姓名"④:组合继承:调用+原型链继承函数Parent(name,age){this.name=name;这个。年龄=年龄;this.ParFunc=function(){console.log(this.height)}}Parent.prototype.sayName=function(){console.log(this)}functionChild(cname,cage,height){Parent.call(this,cname,笼子);//解决参数传递问题this.height=height;};Child.prototype=newParent()Child.prototype.constructor=Child;//将Child指向它自己,否则总是指向Parentvarchild=newChild('testname','testage','testheight')是一种常见的继承方式,缺点是Parent构造函数被调用了两次⑤:寄生组合继承:cal+prototypefunctionParent(name,age){//父函数this.name=name;这个。年龄=年龄;this.ParFunc=function(){console.log(this.height)}}Parent.prototype.sayName=function(){console.log(this)}functionChild(cname,cage,height){//父子函数。call(this,cname,cage)this.height=height;};varcreateObj=function(){//中间函数继承自父函数Trans(){};Trans.prototype=Parent.prototype;returnnewTrans();};Child.prototype=createObj()Child.prototype.constructor=Child;//变回指针varchild=newChild('Name','Age','Height')console.log(child)2:如何获取自定义属性,特例数据-*如何获取官方定义:data-*是**html5**新属性主要用来存放页面的自定义数据,不能包含大写字母(默认会转为小写)注意:自定义属性以"data-"为前缀是被用户代理完全忽略我印象中的第一印象就是getAttribute(),setAttribute()两个属性,一个是get,一个是set,很少用到,但是大部分常用的框架都是使用data-*作为自定义属性,所以在其实在获取data-等自定义属性时,有一个更方便的方法dataset
eg:vardiv1=document.getElementById('div1')console.log(div1.dataset)//DOMStringMap{a:"Test",b:"222"}a:"Test"b:"222"使用data-*作为自定义属性:All属性一句话就可以获取,获取方式也简单三:事件的几个阶段:捕获,target(event.:从最深的节点向外传播,div->window,就像把石头扔到水里一样,层层波浪到达河边-捕获(Netscape):从最外层转移到目标,window->div,就像你去大企业集团找人一样,需要提供company>large离开tment>smalldepartment>group>target-target:触发流程event.target-target和currentTarget的区别:target的属性指向target流程中的DOM对象,即触发事件监听的对象。currentTarget指向当前对象,具体内容同this。当this指向target(事件的目标阶段)时,target与currentTarget相同——现在主流浏览器几乎都支持冒泡;早期版本的IE会跳过html直接跳转到document,不支持抓包。——一般情况下,大部分都是用冒泡的。事件代理(delegation)也利用了事件冒泡的原理,使DOM节点可追溯。也可以利用冒泡的原理做埋点,避免增加新的DOM节点,改代码上线。——事件句柄addEventListener('eventname','function',false),默认冒泡4:判断数据类型,返回数据的具体类型emm...然后直接returntypeofn就完事了,哦不,再次识别数组,因为数组的typeof也是对象,Array.isArray(n).../^12/这个返回什么?wc也是一个对象,那怎么区分呢,对,正则中有个test方法,然后判断if(n.test){return'RegExp'}null好像是返回obj,timeDate,就可以了返回obj,一切皆对象。据说instanceof还可以:左边是否是右边的实例,也就是说我们要判断每一个类型,所以[]instanceofArray//true[]instanceofObject//true不仅是麻烦,而且回报不准确。据说构造函数也是可用的:js引擎会给函数加上一个原型,让它指向'这个函数'的引用/^12/.constructor//fRexExp(){[nativecode]}newDate().constructor//?Date(){[nativecode]}null.constructor//Error:Cannotread..undefined.constructor//Error:Cannotread..发现有些typeof无法验证,但是null和undefined没有‘指针’啊,而且写继承的时候,指针是可以改的,一不留神就爽了。。。把这些综合起来基本就够了,其实不然优雅的。请toString上台....华丽的分割线toString()是Object的原型方法,调用该方法默认返回当前对象的[[Class]]。这是格式为[objectXxx]的内部属性,其中Xxx是对象的类型。完美~~Object.prototype.toString.call(null);//[objectNull]Object.prototype.toString.call(newFunction());//[对象函数]Object.prototype.toString.call(newDate());//[objectDate]但是我觉得除了obj比较特殊,其他类型,typeof都可以判断,没必要再调用toString方法,所以最后封装=>functiontypeDetection(n){if(typeofn==='object'){returnObject.prototype.toString.call(n)}else{returntypeofn}}直接调用typeDetection('')//字符串五:实现千分之一Q:字符:1234567890.12转换为:1,234,567,890.12R:我个人使用while循环函数strFilter(str){letnewStr=String(str).split('.')//对原字符进行分割,兼容Number类型lettransStr=newStr[0],resStr=[]while(transStr/1000>1){//判断是否大于1000letwhildStr=String((transStr/1000).toFixed(3)).split('.')//这里必须保留三位小数,否则正数部分末尾的0会丢失,重新转成String,因为Number没有split方法transStr=wildStr[0]//每次都取小数点前的值(正数部分)resStr。unshift(whildStr[1])//向前插入小数点后的数()}//除以1000,余数+每次除1000后的数+原小数点letres2=newStr[1]?('.'+newStr[1]):''letresComma=resStr.length?(','+resStr.join(',')):''returntransStr+resComma+res2}虽然实现代码很多,但个人觉得很容易理解使用正则,真的很短:functionstrFilter2(n){lets=String(n)letre=/\d{1,3}(?=(\d{3})+$)/gletn1=s.replace(/^(\d+)((\.\d+)?)$/,function(s,s1,s2){returns1.replace(re,'$&,')+s2})返回n1}其实regex在很多场景下都有优势,但是不能轻易想到Q:下面this指向(function(){"usestrict";console.log(this)//undefined})()(function(){"usestrict";console.log(this)//window})()R:在严格模式下,除了构造函数和对象内置函数,this指向undefined问:async和async有什么区别在脚本标签中推迟?R:别说没用,上图什么都没加:脚本读取和解析脚本阶段会阻塞页面执行,添加async:脚本解析脚本阶段会阻塞页面执行添加defer:scriptj脚本会在页面完成解析时执行Q:[1,2,3].map(parseInt)的结果是什么?R:以前用过parseInt,只知道是向下取整。我查了一下w3c中parseInt的定义:Crazy再看map,parseInt是回调函数,map会传递三个参数给parseInt,parseInt只识别前两个,然后就是getfunctionparseInt1(item,index){returnparseInt(item,index)}getparseInt(1,0)parseInt(2,1)parseInt(3,2)parseInt(1,0),parseInt定义的radix不是Pass或者0,按照十进制,你将得到1parseInt(2,1),parseInt定义第二个参数radix位于2-36(0除外),否则返回NaN,所以得到NaNparseInt(3,2)。),但是个人试过parseInt(10,2)=>3,parseInt(20,2)=>6,parseInt(30,2)=>NaN,发现只要第一个字符小于基数,一切皆有可能。但是一旦第一个字符>=radix,就会返回NaN参考文章:四种判断js数据类型的方法