HTML5新增的元素
首先html5为了更好的实践web语义化,增加了header,footer,nav,aside,section等语义化标签,在表单方面,为了增强表单,为input增加了color,emial,data ,range等类型,在存储方面,提供了sessionStorage,localStorage,和离线存储,通过这些存储方式方便数据在客户端的存储和获取,在多媒体方面规定了音频和视频元素audio和vedio,另外还有地理定位,canvas画布,拖放,多线程编程的web worker和websocket协议
css
常用的布局
-
静态布局
宽高固定
-
自适应布局:
布局特点:不同分辨率下,页面元素位置变化,大小不变
实现方法:针对不同分辨率创建对应的样式表,使用 @media 媒体查询给不同尺寸的设备切换不同的样式
缺点:IE8及以下不支持媒体查询;只能兼容主流分辨率
-
流式布局(百分比布局):
布局特点:不同的分辨率下显示相同的排版;高度固定,宽度自适应
实现方法:网页中主要区域的尺寸使用百分比;
缺点:大屏幕上元素被拉长,但是文字,高度还是固定大小,不协调
经典流式布局:左侧固定,右侧自适应;两侧固定,中间自适应
-
弹性布局(rem/em布局):
布局特点:页面元素宽度,高度,字体大小会跟着屏幕大小缩放
实现方法:使用js监听当前屏幕大小,设置html的字体大小
缺点:IE678不兼容;需要计算;
-
响应式布局:
布局特点:每个屏幕分辨率下面会有一个布局样式,即元素位置和大小都会变,响应式设计的目标是确保一个页面在所有终端上(各种尺寸的PC、手机、手表等等)都能显示出令人满意的效果
实现方法:媒体查询+流式布局
优点:适应pc和移动端
缺点:要匹配足够多的屏幕大小,工作量大,设计也需要多个版本
css3新特性
1.过渡 transition 2.动画 animation 3.形状转换 transform 4.阴影 box-shadow 5.滤镜 Filter 6.颜色 rgba 7.栅格布局 gird 8.弹性布局 flex
伪类与伪元素区别
1)伪类(pseudo-classes)
-
其核⼼就是⽤来选择DOM树之外的信息,不能够被普通选择器选择的⽂档之外的元素,⽤来添加⼀些选择器的特殊效果。
-
⽐如:hover :active :visited :link :visited :first-child :focus :lang等
-
由于状态的变化是⾮静态的,所以元素达到⼀个特定状态时,它可能得到⼀个伪类的样式;当状态改变时,它⼜会失去这个样式。
-
由此可以看出,它的功能和class有些类似,但它是基于⽂档之外的抽象,所以叫 伪类。
2)伪元素(Pseudo-elements)
-
DOM树没有定义的虚拟元素
-
核⼼就是需要创建通常不存在于⽂档中的元素,
-
⽐如::before ::after 它选择的是元素指定内容,表示选择元素内容的之前内容或之后内容。
-
伪元素控制的内容和元素是没有差别的,但是它本身只是基于元素的抽象,并不存在于⽂档中,所以称为伪元素。⽤于将特殊的效果添加到某些选择器
2)伪类与伪元素的区别
-
表示⽅法
-
CSS2 中伪类、伪元素都是以单冒号:表示,
-
CSS2.1 后规定伪类⽤单冒号表示,伪元素⽤双冒号::表示,
-
浏览器同样接受 CSS2 时代已经存在的伪元素(:before, :after, :first�line, :first-letter 等)的单冒号写法。
-
CSS2 之后所有新增的伪元素(如::selection),应该采⽤双冒号的写法。
-
CSS3中,伪类与伪元素在语法上也有所区别,伪元素修改为以::开头。浏览器对以:开头的伪元素也继续⽀持,但建议规范书写为::开头
-
-
定义不同
-
伪类即假的类,可以添加类来达到效果
-
伪元素即假元素,需要通过添加元素才能达到效果
-
-
总结:
-
伪类和伪元素都是⽤来表示⽂档树以外的"元素"。
-
伪类和伪元素分别⽤单冒号:和双冒号::来表示。
-
伪类和伪元素的区别,关键点在于如果没有伪元素(或伪类),
-
是否需要添加元素才能达到效果,如果是则是伪元素,反之则是伪类。
-
4)相同之处:
-
伪类和伪元素都不出现在源⽂件和DOM树中。也就是说在html源⽂件中是看不到伪类和伪元素的。 不同之处:
-
伪类其实就是基于普通DOM元素⽽产⽣的不同状态,他是DOM元素的某⼀特征。
-
伪元素能够创建在DOM树中不存在的抽象对象,⽽且这些抽象对象是能够访问到的。
让一个div水平垂直居中
-
使用position + transform
-
使用flex
-
使用position
-
使用伪类
.parent{ font-size: 0; text-align: center; } .parent::before { content: ""; display: inline-block; width: 0; height: 100%; vertical-align: middle; } .child{ display: inline-block; vertical-align: middle; }
link和@import有什么区别
(1)link属于XHTML标签,除了加载CSS外,还能用于定义RSS, 定义rel连接属性等作用;而@import是CSS提供的,只能用于加载CSS;
(2)页面被加载的时,link会同时被加载,而@import引用的CSS会等到页面被加载完再加载;
(3)import是CSS2.1 提出的,只在IE5以上才能被识别,而link是XHTML标签,无兼容问题;
js
数组和对象的原生方法
-
Array
-
Array.concat( ) 合并数组
-
Array.join( ) 将数组元素连接起来以构建一个字符串
-
Array.length 数组的大小
-
Array.pop( ) 删除最后一项,返回所删除的值
-
Array.shift( ) 删除第一项,返回所删除的值
-
Array.push( ) 往数组最后插入数据,返回数组的长度
-
Array.unshift( ) 在数组头部插入数据,返回数组的长度
-
Array.reverse( ) 倒叙
-
Array.slice( ) 截取子数组,返回新值
-
Array.sort( ) 对数组元素进行排序
-
Array.splice( ) 插入、删除或替换数组的元素
-
Array.toLocaleString( ) 把数组转换成局部字符串
-
Array.toString( ) 将数组转换成一个字符串
-
Array.indexof( ) 检测数据中是否含有某个数据
-
Array.forEach( ) 循环数组
-
-
Object
-
Object.hasOwnProperty( ) 检查属性是否被继承
-
Object.isPrototypeOf( ) 一个对象是否是另一个对象的原型
-
Object.propertyIsEnumerable( ) 是否可以通过for/in循环看到属性
-
Object.toLocaleString( ) 返回对象的本地字符串表示
-
Object.toString( ) 定义一个对象的字符串表示
-
Object.valueOf( ) 指定对象的原始值
-
-
ES6
-
Array.from() 将类数组对象或可迭代对象转化为数组。
-
Array.of() 形成新数组,
-
map() 遍历数组,返回一个新数组,不改变原数组
-
filter() 过滤掉数组中不满足条件的值,返回一个新数组,不改变原数组。
-
reduce() 让数组的前后两项进行某种计算,然后返回其值,并继续计算,不改变原数组,返回计算的最终结果。
-
some() 用于遍历数组每一项,有一项返回true,则停止遍历,结果返回true。不改变原数组
-
every() 用于遍历数组每一项,每一项返回true,最终结果为true.有一项返回false,停止遍历,结果返回为false。不改变原数组。
-
find() 方法找到第一个符合条件的成员,没有符合的则返回 undefined
-
findIndex 方法的用法与 find方法非常类似,返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回-1。
-
fill() 方法使用给定值, 填充一个数组,fill 方法还可以接受第二个和第三个参数,用于指定填充的起始位置和结束位置
-
copyWithin() 将一定范围索引的数组元素修改为此数组另一指定范围索引的元素
-
includes() 数组是否包含指定值,返回布尔值
-
entries(),keys()和 values()——用于遍历数组,可以用 for...of 循环进行遍历,唯一的区别是 keys(是对键名的遍历、values()是对键值的遍历,entries()是对键值对的遍历 foreach() 用于遍历数组,无返回值,不改变原数组,仅仅只是遍历,常用于注册组件、指令等等
-
内存泄漏
内存泄露
-
指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况。内存泄漏并非指内情人q存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,失去了对该段内存的控制,因而造成了内存的浪费
-
排查
一)是否App中的类中和引用变量过多使用了Static修饰 如public staitc Student s;在类中的属性中使用 static修饰的最好只用基本类型或字符串。如public static int i = 0; //public static String str;
二)是否App中使用了大量的递归或无限递归(递归中用到了大量的建新的对象)
三)是否App中使用了大量循环或死循环(循环中用到了大量的新建的对象)
四)检查App中是否使用了向数据库查询所有记录的方法。即一次性全部查询的方法,如果数据量超过10万多条了,就可能会造成内存溢出。所以在查询时应采用“分页查询”。
五)检查是否有数组,List,Map中存放的是对象的引用而不是对象,因为这些引用会让对应的对象不能被释放。会大量存储在内存中。
六)检查是否使用了“非字面量字符串进行+”的操作。因为String类的内容是不可变的,每次运行"+"就会产生新的对象,如果过多会造成新String对象过多,从而导致JVM没有及时回收而出现内存溢出。
内存溢出
-
内存溢出是由于没被引用的对象(垃圾)过多造成JVM没有及时回收,造成的内存溢出
-
引起内存溢出的原因
-
内存中加载的数据量过于庞大,如一次从数据库取出过多数据;
-
集合类中有对对象的引用,使用完后未清空,使得JVM不能回收;
-
代码中存在死循环或循环产生过多重复的对象实体;
-
使用的第三方软件中的BUG;
-
启动参数内存值设定的过小
-
写JavaScript的基本规范
-
不要在同一行声明多个变量。
-
请使用 ===/!==来比较true/false或者数值
-
使用对象字面量替代new Array这种形式
-
不要使用全局函数。
-
Switch语句必须带有default分支
-
函数不应该有时候有返回值,有时候没有返回值。
-
For循环必须使用大括号
-
If语句必须使用大括号
-
for-in循环中的变量 应该使用var关键字明确限定作用域,从而避免作用域污染。
JS的数据类型
基本类型:Number、Boolean、String、null、undefined、symbol(ES6 新增的),BigInt(ES2020) 引用类型:Object,对象子类型(Array,Function)
浅拷贝和深拷贝的区别
-
浅拷贝:一般指的是把对象的第一层拷贝到一个新对象上去
-
深拷贝:一般需要借助递归实现,如果对象的值还是个对象,要进一步的深入拷贝,完全替换掉每一个复杂类型的引用。
浅拷贝:浅拷贝通过ES6新特性Object.assign()或者通过扩展运算法...来达到浅拷贝的目的,浅拷贝修改 副本,不会影响原数据,但缺点是浅拷贝只能拷贝第一层的数据,且都是值类型数据,如果有引用型数据,修改 副本会影响原数据。
深拷贝:通过利用JSON.parse(JSON.stringify())来实现深拷贝的目的,但利用JSON拷贝也是有缺点的, 当要拷贝的数据中含有undefined/function/symbol类型是无法进行拷贝的,当然我们想项目开发中需要 深拷贝的数据一般不会含有以上三种类型,如有需要可以自己在封装一个函数来实现。
事件监听
addEventListener()方法,用于向指定元素添加事件句柄,它可以更简单的控制事件,语法为
element.addEventListener(event, function, useCapture);
第一个参数是事件的类型(如 "click" 或 "mousedown").
第二个参数是事件触发后调用的函数。
第三个参数是个布尔值用于描述事件是冒泡还是捕获。该参数是可选的。
事件传递有两种方式,冒泡和捕获
事件传递定义了元素事件触发的顺序,如果你将P元素插入到div元素中,用户点击P元素,
在冒泡中,内部元素先被触发,然后再触发外部元素,
捕获中,外部元素先被触发,在触发内部元素,
事件委托以及冒泡原理
事件委托是利用冒泡阶段的运行机制来实现的,就是把一个元素响应事件的函数委托到另一个元素,一般是把一组元素的事件委托到他的父元素上,委托的优点是
减少内存消耗,节约效率
动态绑定事件
事件冒泡,就是元素自身的事件被触发后,如果父元素有相同的事件,如onclick事件,那么元素本身的触发状态就会传递,也就是冒到父元素,父元素的相同事件也会一级一级根据嵌套关系向外触发,直到document/window,冒泡过程结束。
事件冒泡和事件捕获
事件捕获(event capturing): 当鼠标点击或者触发dom事件时(被触发dom事件的这个元素被叫作事件源),浏览器会从根节点到事件源(由外到内)进行事件传播。
事件冒泡(dubbed bubbling):事件冒泡刚好相反,事件源到根节点(由内到外)进行事件传播。
无论是事件捕获还是事件冒泡,它们都有一个共同的行为,就是事件传播。dom标准事件流的触发的先后顺序为:先捕获再冒泡。即当触发dom事件时,会先进行事件捕获,捕获到事件源之后通过事件传播进行事件冒泡。
在我们平常用的addEventListener
方法中,一般只会用到两个参数,一个是需要绑定的事件,另一个是触发事件后要执行的函数,然而,addEventListener
还可以传入第三个参数,第三个参数默认值是false,表示在事件冒泡阶段调用事件处理函数;如果参数为true,则表示在事件捕获阶段调用处理函数。
JS中的垃圾回收机制
一、为什么要垃圾回收
如果没有垃圾回收机制,适时清理不被引用的值并释放相应的内存空间,JavaScript 解释器将会消耗完系统中所有可用内存,造成系统崩溃。
二、垃圾回收的核心思路
所谓垃圾回收的核心思想就是清理掉内存中不再被引用的值,通俗的说,就是清理掉内存中没用的值,那么如何判断有没有用?如果是局部变量,在函数调用结束后即是无用的,可以被回收掉;而全局变量在浏览器卸载页面的时候才会消失。由于这个过程消耗较大,所以解释器会按照固定时间周期性的执行回收。
三、垃圾回收的两种方式
1.标记清除(JS最常用)
标记清除法主要有以下三个步骤:
1)给所有变量增加一个标记,如果是进入执行环境(比如申明变量),则标记为“进入环境”,如果是结束执行环境(比如执行完相关函数),则标记为“离开环境”;
2)去掉“进入环境”的变量标记以及被该变量所引用的变量标记(比如闭包);
3)还存在标记的变量即是需要被清理的变量。
2.引用计数
引用计数法主要有以下三个步骤:
1)申明了一个变量,并且将一个引用类型的值赋值给这个变量,那么这变量的引用就加1;
2)如果这个变量的值又指向另外一个值,或者说这个变量被重新赋值了,那么以上的引用类型的值的引用次数就减1;
3)如此一来,该引用类型的值的引用次数即为0,垃圾回收器会在运行的时候清理掉引用次数为0的值并释放相应的内存空间;
4)特别注意:引用计数在代码中存在循环引用时会出现问题
判断数组的方法
Object.prototype.toString.call()、instanceof、Array.isArray()以及typeof
面向对象
面向对象的三大特性:继承/多态/封装
-
封装
封装最好理解了。封装是面向对象的特征之一,是对象和类概念的主要特性。封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。
-
继承
继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。通过继承创建的新类称为“子类”或“派生类”,被继承的类称为“基类”、“父类”或“超类”。
要实现继承,可以通过“继承”(Inheritance)和“组合”(Composition)来实现。
-
多态性
多态性(polymorphisn)是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。
实现多态,有两种方式,覆盖和重载。覆盖和重载的区别在于,覆盖在运行时决定,重载是在编译时决定。并且覆盖和重载的机制不同,例如在 Java 中,重载方法的签名必须不同于原先方法的,但对于覆盖签名必须相同。
作用域链
全局函数无法查看局部函数的内部细节,但局部函数可以查看其上层的函数细节,直至全局细节。 当需要从局部函数查找某