知识总结
css模块
1. 框模型默认的计算方式是什么?要改变默认的计算方式用哪个属性及值?
- 标准盒模型: 总宽度=width+margin+border+padding
- 怪异盒模型: 总宽度=width+margin
- box-sizing :
- content-box: width=内容宽度
- padding-box(有兼容性问题): width=内容宽度+padding(left,right)
- border-box: width=内容宽度+padding(left,right)+border(left,right)
- box-sizing :
2. 单位 : % px em rem vh vw
- em: 相对于父元素的字体大小的单位
- rem:相对于根元素的字体大小的单位
- vw: 1vw 等于可视窗口宽度的1%
- vh: 1vh 等于可视窗口高的的1%
3.定位类型
- Fixed,固定定位是相对于浏览器窗口的定位,脱离文档流;
- Relative,相对定位,相对于自身起点进行移动,不脱离文档流;
- Absolute,绝对定位,相对于最近的已定位元素进行移动,若没有则相对于,脱离文档流;
- Sticky,粘性定位,元素定位表现为在跨越特定阈值前为相对定 位,之后为固定定位;
- Static:默认值,没有定位,元素出现在正常的流中(忽略 top, bottom, left, right或者 z-index 声明)。
- inherit:规定应该从父元素继承position属性的值。
4.隐藏网页中的元素有几种方式?这些方法有什么区别?
- display:none; 脱离文档流,不占页面空间,会改变页面布局;
- visibility:hidden ;不会脱离文档流,不会改变页面布局,仍占页面空间;
- opacity:0,该元素隐藏起来了,但不会改变页面布局,并且,如果该元素已经绑定一些事件,如click事件,那么点击该区域,也能触发点击事件;
- input框的type=hidden,也可隐藏.
5.如何编写响应式网页?
- 声明viewport元标签
- 所有容器/文字/图片 使用相对尺寸
- 流式布局+弹性布局
- CSS3 Media Query + px
- CSS选择器优先级
- 补充优先级:!important>内联样式>内部样式>外部样式
- 权值大小:行内样式(1000)/id选择器(100)/属性选择器,class选择器,伪类选择器(10)/元素选择器,为元素选择器(1)/通配符(0)
6.如何实现元素水平垂直居中?
- 定位 + 外边距(盒子宽高已知)
.son {
position: absolute;
left: 50 % ;
top: 50 % ;
margin-left: -自身一半宽度;
margin-top: -自身一半高度;
}
- flex 布局(设置x y 轴上元素的对齐方式)
.father:{
display: flex;
align-items: center;
justify-content: center;
}
- 定位 + transform 盒子高宽已知
#container {
position: relative;
border: 1 px solid red;
width: 800 px;
height: 600 px;
}
#center {
width: 100 px;
height: 100 px;
background: blue;
position: absolute;
top: 50 % ;
left: 50 % ;
transform: translate(-50 % , -50 % );
}
- 视窗居中(vh为视口单位)
#center {
margin:50vh auto 0;
transform: translate(-50%)
}
- margin: auto
.father {
width: 300px;
height: 150px;
position: relative;
}
.son {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
width: 200px;
height: 100px;
margin: auto; // 自动计算平分上下,左右外边距
}
7.弹性布局详细属性(容器与项目)
#container: {
display: flex;
flex-direction: row ; //row-reverse|column|column-reverse; 主轴对齐方式
justify-content: center; //flex-start|flex-end|space-between|space-evenly|space-around交叉轴对齐方式
flex-wrap: nowrap; //wrap|wrap-reverse;是否换行
flex-flow: row wrap; //flex-wrap+flex-direction
align-item: normal; // flex-start|flex-end|center|baseline|stretch(item无高)单个项目在交叉轴对齐方式
aligin-content:stretch;//flex-start|flex-end|center|space-between|space-evenly|space-around //多行item在交叉轴的对齐方式
}
.item: {
order: number(- 0 +); //值越小排列越靠前
align-self: auto;(继承align-item,无则=stretch) //stretch|flex-start|flex-end|center|baseline
flex-grow: 0; //项目放大比例
flex-shrink: 1; //项目缩小比例
flex-basis: auto; //项目基础大小
flex: 0 1 auto; // auto(1 1 auto)|none(0 0 auto) //flex-grow+flex-shrink+flex-basis
}
8.清除浮动的方法
- 使用带 clear:both属性的空元素
- 浮动元素添加 overflow:hidden;(使用了BFC规则)
- 使用伪元素选择器
div:after { display: block; content: ‘ ’; clear: both; height:0; overflow:hidden}
div{ zoom:1; } /** 兼容ie触发hasLayout */
附:外边距溢出(上外边距溢出,下外边距溢出)处理办法:
- 前后添加table标签;
- 添加伪元素标签 :
:after(或者:before){
display:table,
content:' '
}
9.BFC规则(清除浮动,防止margin重叠)
格式化上下文,形成一个独立的渲染区域,规定了内部如何布局,并且这个区域的子元素不会影响到外面的元素,起重比较重要的布局规则有
内部box垂直放置,计算BFC的高度时,浮动元素也参与计算,
- 触发BFC的规则有根元素,
- <html>根元素
- float的值不为none;
- position为不为relative和static的元素;
- display:inlink-block,table-cell,tab-caption,flex,inline-flex;
- overflow不为visible的元素(auto,scroll,hidden);
10.link 标签和 import 标签的区别
- link 属于html标签,而@import是css提供的
- 页面被加载时,link会同时被加载,而@import 引用的css会等到页面加载结束后加载.
- link 是 html 标签,因此没有兼容性,而@import 只有 IE5 以上才能识别.
- link 方式样式的权重高于@import 的.
11.Transfrom和animation的区别
Animation 和 transition 大部分属性是相同的,他们都是随时间改变元素的属性值,他们的主要区别是 transition 需要触发一个事件
才能改变属性,而 animation 不需要触发任何 事件的情况下才会随时间改变属性值,并且 transition 为 2 帧,从 from .... to,
而 animation 可以一帧一帧的。
12.display: table和本身的table有什么区别?
display: table的css声明能够让一个html元素和它的子节点像table元素一样,使用基于表格的css布局,能够轻松的定义一个单元格的边界,
背景等样式,而不会产生因为使用了table那样的制表标签导致的语义化问题.
之所以现在淘汰了table系表格元素,是因为用div+css编写出来的文件比table编写出来的文件小,而且table必须在页面完全加载后才显示,
div则是逐行显示,table的嵌套太多,没有div简洁
13.inline-block,inline和block的区别?为什么img是inline还可以设置宽高
- block(块级元素),单独成行,可以设置宽高,margin/padding水平垂直都有效
- inline(行内块元素),宽高无效,margin垂直方向无效,padding水平垂直都有效
- inline-block(行内块,),宽高有效,margin/padding水平垂直都有效
- img元素同时属于替换元素,所有的替换元素都是行内元素input/textarea/select/object
14.重排重绘?减少重排重绘的方法?
- 重排(几何属性引起的):DOM的变化影响到了元素的几何属性,并且页面中其他元素的几何属性可能会受到影响,浏览器需要重新计算元素的集合属性,页面中其他元素的集合属性可能受到了影响,浏览器需要重新构造renderTree渲染树的过程.
- 重绘(可能是几何也可能是非几何引起的):浏览器将重新构造的渲染树渲染到屏幕上的过程.
- 引起的原因:
- 添加或删除可见的DOM元素;
- 元素尺寸的变化;
- 浏览器页面初始化;
- 浏览器窗口大小发生改变;
- 减少重排重绘
- 不在布局信息改变时做DOM查询;
- 使用csstext,className一次性改变属性;
- 使用fragment;
- 对于多次重排的元素(如动画),使用绝对定位脱离文档流,时期不影响其他元素
15.JS动画和CSS3动画的差异性
渲染线程分别为main thread 和compositor thread,如果 CSS动画只改变transform和opacity,这时整个CSS动画得以在compositor thread 完成
(而JS动画则会在main thread ,然后触发compositor 进行下一步操作),特别注意的是如果改变transform和opacity是不会layout(重排)或者paint(重绘)的.
- 区别:
- 功能覆盖面,JS比CSS大;
- 实现/重构难度不一,CSS3比JS更加简单,性能调优方向固定;
- 对帧速表现不好的低版本浏览器,CSS3可以做到自然降级;
- CSS动画有天然事件支持;5)CSS3有兼容性问题;
16.用CSS画一条0.5px的线(针对retina屏)
<style>
.parent {
Position: relative;
$:after {
position: absolute;
bottom: 0;
left: 0;
right: 0;
content: '';
box-sizing: border-box;
height: 1px;
border-bottom: 1px solid rgba(0,0,0,0.2);
transform: scaleY(0.5);
transform-origin: 0 0;
}
}
</style>
<div class='parent'></div>
17.画一个三角型
#triangle-up {
width: 0;
height:0;
border-left: 50px solid transparent;
border-right:50px solid transparent;
border-bottom: 100px solid red;
}
18.百分比布局
当浏览器宽度或者高度发生变化时,通过百分比单位使得浏览器中的组件的宽和高也发生变化,从而实现响应式效果;
- 百分比单位中:
- 子元素的height,width,padding,margin,border完全直接相对于父元素的width,但
- border-radius,translate,background-size等都是相对于自身的.
- eg: 实现4:3长方形
.trangle {
height:0;
width:100%;
padding-top:75%;
}
- 问题:
- 计算困难;
- 所有属性使用百分比,相对于父元素的属性不唯一,造成布局问题复杂
- 优化,可以使用vw/vh替代,任意层级元素在使用vw大卫的情况下,1vw都等于试图宽度的百分之一;
- 关于vw补充,移动端iphone6/7 375*667分辨率,px转换vw,
1px = (1/375) * 100 vw ;2)通过postcss-px-to-viewport插件预处理css自动将px转化成vw
19.CSS Media Query
媒体查询类型:screen(电脑,ipad,手机) /all(所有设备)/print(打印机,打印预览)/speech(屏幕阅读器等发声设备)
屏幕尺寸:375px/376-767px/768-1199px/1200px
20.设置背景图片自适应,居中显示
.background {
width: 300px;
height: 150px;
background: url('./favicon.ico') no-repeat;
background-size: contain;
background-position: 50% 50%; //center
}
21.Html5
- 语义标签<header><footer><nav><section><article><dialog><time>
- 增强型表单(增强属性,新增表单元素,新增表单属性)
- color,data,url,datetime,email,number,tel等
- <datalist><progress><meter><keygen><output>
- placeholder,required,min/max,height/width,autofocus,multiple,step
- 视频和音频
- Canvas绘图
- SVG绘图(XML格式定义图形,可伸缩矢量图)
- 地理定位(navigatior.geolation.getCurrentPosition)
- 拖放API(<div draggable=
true
></div>) - webWorker(eeb Worker 可以通过加载一个脚本文件,进而创建一个独立工作的线程,在主线程之外运行)
- webStorage(localStorage,sessionStorage)
- webScoket (为web应用程序客户端和服务器端之间提供一种全双工的通信机制)
- 握手阶段采用HTTP协议,默认端口是80和443
- 建立在TCP协议基础之上,和http协议属于同应用层
- 可以发送文本,也可以发送二进制数据
- 没有同源策略,客户端可以与任意服务器通信
- 协议标识符是ws(如果加密是,wss),如ws://localhost:8023
22.CSS3
- 新增选择器
- border (border-radius,border-img,border-shadow)
- background (clip,origin,size,break)
- text(word-wrap,text-overflow,text-shadow)
- color (rgba,hala)
- transition 过渡
- transform
- animation
- linear-gradient(渐变)
- flex+grid
js模块
1.JavaScript都有哪些数据类型?
- 原始类型: 数值型/字符串型/布尔型/未定义型/null
- 引用类型: 对象
2.Typeof(适合用于变量是否为原始类型的判断)返回的类型有哪些?
- 可以检测 Number String boolean undefined object Function
- 不能返回: Array Date 不一定:RegExp(返回Object)
- 检测null返回object,检测Promise返回Function
- 补充 :
- instanceof // 检测函数的原型对象是否出现在对象的原型链上
- isPrototypeof // 检测对象是否出现在另一个对象的原型链上
3.同步和异步有何区别?
同步:指发送一个请求,需要等待返回,然后才能够发送下一个请求,有个等待过程
异步:指发送一个请求,不需要等待返回,随时可以再发送下一个请求,即不需要等待。
4.函数的几种定义方法
- 直接声明
function 函数名(参数列表){ 函数体; return 返回值}
问题: 会被声明提前!
解决:用赋值的方式就不会被声明提前。 - 赋值方式
var函数名=function (参数列表){ 函数体; return 返回值}
优势: 不会被声明提前 - 用new
var 函数名=new Function(“参数1”,“参数2”,…,“函数体;…”)
5.原型与原型链?原型链的顶端是什么?Object的原型是什么?Object的原型的原型是什么?在数组的原型脸上实现删除数组重复数据的方法?
- 原型:每一个函数都有一个prototype属性,这个属性指向函数的原型对象;
- 原型链: proto 这是每个对象(除null外)都会有的属性,叫做__proto__,这个属性会指向改对象的原型;这种链式指向结构叫;做原型链;
- 原型是一个对象,是用Object构造函数生成的,Object.prototype没有原型,Object.prototype.proto===null;
Object的原型为Object.prototype
Object.prototype.__proto__=null // Object的原型的原型是null
Array.prototype.XXX=
6.如何理解JSON?
JSON是JS对象的一种表现方式,即以js对象的数据格式表现出来的字符串
- 将JSON字符串转换成JSON对象(反序列化) JSON.parse()
- 将JSON对象转换成JSON字符串(序列化) JSON.stringify()
- 补充(JSON方法深拷贝缺陷)
- Date 对象变为字符串
- RegExp、Error 对象变为空对象 {}
- 函数、undefined、Symbol 属性丢失
- NaN、Infinity、-Infinity 变为 null
- enumerable 为 false 的属性丢失
- 循环引用的对象不能正确拷贝
7.判断以下程序的输出结果:
for(var i=0;i<5;i++){
setTimeout(function(){
console.log(i);
},0)
}
怎么打印 0 1 2 3 4 ? var改为let.
8.闭包是什么,有什么特性,对页面有什么影响?
闭包:当函数能够记住并访问当前所在的词法作用域,即使函数是在当前词法作用域之外执行,这时就产生了闭包
(是一种既重用变量,又保护变量不被污染的一种机制).
- 特性:闭包是用外层函数包裹受保护的变量和内层函数对象,外层函数将内层函数对象返回到外部,使用者调用外层函数,获得返回的内层函数
- 应用场景
- 应用了回调函数的场景(定时器,事件监听,Ajax 请求,跨窗口通信,Web Worker或者其他的异步(或者同步)任务中
- 模块
- 影响:由于闭包时,变量的值都保存到内存中,会导致页面加载时内存消耗很大
- 解决:使用完释放闭包,变量赋值为null
9.ES5/ES6特性
- Es5
- 严格模式 ‘use strict’
- 语法改变:
- 变量必须先声明后使用,静默升级为错误(禁止使用未声明变量);
- 自定义函数(匿名函数/回调函数)this不再指向window,指向undefined
- eavl函数将创建局部作用域,不再为全局;
- 对象不能有同名属性,不使用严格模式时,后书写的同名属性会覆盖之前的属性
- 优点:
- 消除不安全之处,保证安全运行
- 提升编译效率
- 未来发展趋势
- JSON方法
Json对象(数组)转字符串(序列化)JSON.stringify()/字符串转换为json对象(数组)(反序列化)JSON.parse() - Object.create(prototype,[descriptors]) //以指定对象为原型对象创建新的对象
- Object.defineProperty()和Object.defineProperties()访问器属性
- forEach/map/filter/reduce/reduceRight/some/every/indexOf/lastIndesOf/for in
- call(参数为列表)/apply(参数为数组)/bind(永久替换)
- Es6(2015)
Let/const/箭头函数/模板字符串/解构赋值/for of/Es module/set/展开运算符/函数默认参数/class/promise/symbol/Proxy
- et和const
- let声明变量和const声明常量,两个都有块级作用域,const一旦声明运行期间无法修改(原始类型无法修改,引用类型不改变地址可以修改内部属性);ES5中是没有块级作用域的,并且var有变量提升,在let中,使用的变量一定要进行声明
- Var,Let,const的区别(作用域映射,声明,声明与赋值,声明与使用)
- 1)var声明变量可以重复声明,而let不可以重复声明;
- 2)Var 不受限块级作用域,let,const受限于块级作用域
- 3)Var 与window映射,let和const不与window映射;
- 4)Var 声明提前(先赋值再声明),const和let在声明上访问会报错(let不允许先赋值再声明,但可以声明后赋值或不赋值,const声明后必须赋值;)
- 5)Let和const禁止使用未声明变量,var 使用未声明变量会自动在全局上下文声明;
- 补充:条件声明,在使用var声明时,声明提升导致引擎将多次声明合并为一个在作用域顶端(条件声明模式:引擎检测同级上下文多次重复声明,将其合并为一次声明),同名声明不会引发同名错误,let的作用域是块,不可能检查在之前是否使用let声明过同名变量,所以重复声明会引发同名错误,也就不可能在没有声明的情况下声明它;
- 暂时性死区(TDZ),由于代码中的变量还没有初始化而不能被引用的情况
- 箭头函数
匿名函数,自带this保持为定义所在对象 - 模板字符串
模板字符串是增强版的字符串,用反引号(`)标识,${}插入js表达式 - 解构赋值
ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值
let{name,age} = {name:‘zhangsan’,age:33} - for of循环
for…of循环可以遍历数组、Set和Map结构、某些类似数组的对象、对象,以及字符串 - import、export导入导出
ES6标准中,Js原生支持模块(module)。将JS代码分割成不同功能的小块进行模块化,将不同功能的代码分别写在不同文件中,各模块只需导出公共接口部分,然后通过模块的导入的方式可以在其他地方使用
Es module
导入通过import关键字
// 只导入一个
import {sum} from "./example.js"
// 导入多个
import {sum,multiply,time} from "./exportExample.js"
// 导入一整个模块
import * as example from "./exportExample.js"
导出通过export关键字
//可以将export放在任何变量,函数或类声明的前面
export var firstName = 'Michael';
export var lastName = 'Jackson';
export var year = 1958;
//也可以使用大括号指定所要输出的一组变量
var firstName = 'Michael';
var lastName = 'Jackson';
var year = 1958;
export {firstName, lastName, year};
//使用export default时,对应的import语句不需要使用大括号
let bosh = function crs(){}
export default bosh;
import crc from 'crc';
//不使用export default时,对应的import语句需要使用大括号
let bosh = function crs(){}
export bosh;
import {crc} from 'crc';
- set数据结构
Set数据结构,类似数组。所有的数据都是唯一的,没有重复的值。它本身是一个构造函数
Let a = new Set([1,2,2,3,3,3]);console.log(a)//Set {1,2,3}
let arr = [12,43,23,43,68,12];let item = [...new Set(arr)];
console.log(item);//[12, 43, 23, 68]
- Map数据结构
Map映射:也称dictionary字典,一个键值结构,类似于js的对象类型;
eg:Let map = new Map(); map.set(‘name’:”憨憨”);console.log(map)//Map {“name” => “憨憨”};console.log(map.get(“name”)) - … 展开运算符,取代Object.assign()
可以将数组或对象里面的值展开;还可以将多个值收集为一个变量 - 函数默认参数
- class 类的继承
ES6中不再像ES5一样使用原型链实现继承,而是引入Class这个概念 - promise
Promise是异步编程的一种解决方案,比传统的解决方案(回调函数和事件)更合理、强大 - Symbol
Symbol是一种基本类型。Symbol 通过调用symbol函数产生,它接收一个可选的名字参数,该函数返回的symbol是唯一的 - Proxy代理
使用代理(Proxy)监听对象的操作,然后可以做一些相应事情
ES7(2016)
1)修饰器 @
decorator是一个函数,用来修改类甚至于是方法的行为。修饰器本质就是编译时执行的函数
ES8(2017)
1)async、await
使用 async/await, 搭配promise,可以通过编写形似同步的代码来处理异步流程, 提高代码的简洁性和可读性,async 用于申明一个 function 是异步的, 而 await 用于等待一个异步方法执行完
10.理解 async/await以及对Generator的优势
async await 是用来解决异步的,async函数是Generator函数的语法糖
使用关键字async来表示,在函数内部使用 await 来表示异步;async函数返回一个 Promise 对象,可以使用then方法添加回调函数;当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句;
async较Generator的优势:
(1)内置执行器。Generator 函数的执行必须依靠执行器,而 Aysnc 函数自带执行器,调用方式跟普通函数的调用一样
(2)更好的语义。async 和 await 相较于 * 和 yield 更加语义化
(3)更广的适用性。yield命令后面只能是 Thunk 函数或 Promise对象,async函数的await后面可以是Promise也可以是原始类型的值
(4)返回值是Promise。async 函数返回的是 Promise 对象,比Generator函数返回的Iterator对象方便,可以直接使用 then() 方法进行调用
11.迭代相关
- 可迭代对象(具有iterable接口的对象)
Str,Array,Set(集合),Map(映射),arguments(类数组对象),NodeList等DOM集合类型;
Object默认不具备iterable接口(不能使用for of遍历) - 支持可迭代协议的原生语言特性
For of/数组解构/扩展操作符/Array.from()/创建集合/创建映射/
promise.all/promise.race/yield*操作符 - 以闭包形式创建的迭代器也实现了iterable接口,也可用于需要迭代的场景
12.字符串常用方法
- […“abcd”] = [“a”,“b”,“c”,“d”] //字符串解构
- Str.Startwith(searchstring,str,start)//字符串匹配,返回布尔值
- Str.chartAt() //返回指定位置的字符
Str.substr(start,length) //长度截取,返回值截取的字符串- Str.substring(start,stop) //下标截取,不包含stop,stop非负,返回新的字符串,start=stop,返回空串;start>stop,截取之前交换参数;start<0||stop<0,start||stop=0
- Str.slice(start,end) //下标截取,不包含end,end可负,返回新的字符串
- Str.concat() //拼接字符串,返回新字符串
- Str.split() //以指定分隔符将字符串切割成数组
- Str.trim()|trimLeft()|trimRight()//创建副本,删除字符串(前后|左|右)空格,返回副本
- Str.indexOf(str,start) //查找字符串,返回第一个匹配字符的位置或-1,start可选参数
- Str.laseIndexOf() //indexOf从左向右查询,lastIndexOf从右向左查询
- Str.toLowerCase() //字符串全部转小写
- Str.toUpperCase() //字符串全部转大写
- Str.replace(str1,str2) //替换字符串
- Str.includes(str,start) //检索整个字符串,start为起始位置(可选参数)
- Str.startWith(str,start) //左侧开始检索,start为起始位置(可选参数)
- Str.endWith(str,start) //右侧开始检索,start为起始位置(可选参数)
- Str.repeat(count) //将字符串复制count次返回
- Str.padStart(sumlength,copystr)//扩充字符串至指定长度,头部填充(可选,默认空格)
- Str.padEnd(sumlength,copystr) //扩充字符串至指定长度,尾部填充(可选,默认空格)
附,slice/substr/substring参数为负规则;
- slice()将两个负参数当成其与当前字符串长度相加参数;
- substr()第一个参数为负当成其与字符串长度相加参数,第二个负参数转换为0;
- substring()将所有负参数转换为0
13.对象常用方法
1 原型方法
- Object.assign(target,…source) //将源对象上可枚举属性拷贝到目标对象上,返回目标对象
- Object.create(proto,[properitiesobject])//创建一个拥有指定原型与属性的对象
- Object.entries(obj) //var obj={name:dong,age:10}=>[[name,dong],[age,10]]
- Object.keys(obj) //var obj={name:dong,age:10}=>[name,age]
- Object.values(obj) //var obj={name:dong,age:10}=>[dong,10]
- Object.is(value1,value2) //判断两个值(任何类型都可以)为否为同一个值
2. 实例方法
- obj.hasOwnproperty(propertyname) //检测对象是是否包含某个属性
- obj.isPrototypeof(obj2) //检测对象是否是另一个对象的原型
- Obj.prototypeIsEnumerable(propertyname)//判断对象给定属性是否可以被for-in枚举
- Obj.toLocalString() //返回对象的字符串表示,返回与本地环境一致(如时间,带AM,PM)
- Obj.toString() //返回对象的字符串表示
- Obj.valueOf() //返回对象对应的字符串,数值,布尔值表示
14.数组常用方法
1. 不改变原数组
-
Array.concant(otherArr) //传入元素或数组,合并至数组上,返回值为新的数组
-
Array.slice(start,end) //剪切数组(不含end),返回值为剪切之后的元素
-
Array.toString() //数组元素转字符转拼接逗号返回,返回值为拼接元素字符串
-
Array.indexOf()|lastIndexOf() //返回第一个匹配到的元素在数组中的位置或-1
-
Array.includes() //查找元素,返回布尔值
-
Array.valueOf(); //返回Array对象的返回值
附:如果数组中某一项是null或者undefined,数组的 toString()/toLocalString()/join()/valueOf()返回的结果中会议空字符串表示 -
Array.from(); //将可迭代对象转化为数组,返回值为新数组
-
Array.of(); //使用new Array()创建数组,只有一个number类型参数时会创建一个[empty × 3]空数组,使用of可避免
-
arr.keys()|values()|entries() //返回数组索引|元素|索引/元素对的迭代器(配合from转化为数组实例)
eg:Array.from(arr.keys())->[1,2,3]->[0,1,2] -
Array.forEach //将数组执行传进的函数,没有返回值
-
Array.map //将数组按照传进函数执行,返回新数组,没有改变原数组
-
Array.filter //将所有的元素进行判断,将满足条件的元素作为一个新数组返回
-
Array.every //对所有元素进行判断,返回布尔值,全部满足返回true
-
Array.some //对所有元素进行判断,返回布尔值,存在满足返回true
-
Array.reduce //将所有元素调用传入函数,返回值为最后结果
-
Array.find //将所有元素按照测试函数进行查找,返回值为满足条件的第一个元素
-
Array.findIndex //将所有元素按照测试函数进行查找,返回值为第一个满足元素下标
2.改变原数组
- Array.join() //将数组以指定方式切割为字符串;
- Array.splice() //删除,插入,替换数组元素;返回值为被删除的元素,没有则为空数组删:[start,length]/插:[start,0,要插入的元素]/替换:[start,1,要插入的元素]
- Array.reverse() //反转数组的顺序,返回值为重新排序的数组;
- Array.sort() //排序,返回值为排序后的新数组
- Array.push() //数组末尾推入元素,返回值为新数组长度
- Array.pop() //末尾删除,返回值为被删除的元素
- Array.shift() //头部删除,返回值为被删除的元素
- Array.unshift() //头部添加,返回值为新数组的长度
- Array.fill() //按照指定规则填充数组,返回值为填充后的数组
- Array.copyWithin() //按照指定规则复制自身片段填充自身指定位置,返回改变后数组
15.for of、for in、forEach
- forEach:定义:用于调用数组的每个元素,并将元素传递给回调函数
- 缺点:
- 不能同时遍历多个集合,在遍历的时候无法修改和删除集合数据
- 方法不能使用break,continue语句跳出循环,或者使用return从函数体返回
- 对于空数组不会执行回调函数
- 优点:便利的时候更加简洁,效率和for循环相同,不用关心集合下标的问题,减少了出错的效率
- 缺点:
- for in:定义:用于循环遍历数组或对象属性,for in循环里面的index是string类型的,代码每执行一次,就会对数组的元素和属性或者对象的属性进行一次操作
- 缺点:
- 某些情况下,会出现随机顺序的遍历,
- 因为里面的值是string类型,所以增加了转换过程,因此开销较大
- 原型上的属性也会被遍历到,需要添加自身属性判断
- 优点:可以遍历数组的键名,遍历对象简洁方便
- 缺点:
- for of: 定义:(可遍历map,array,set string等)用来遍历可迭代对象(迭代具有iterator接口的可迭代对象),遍历对象可通过转化为数组(Object.keys或Object.values)
- 优点:
- 避免了for in的所有缺点,可以使用break,continue和return,
- 不仅支持数组的遍历,还可以遍历类似数组的对象,支持字符串的遍历最简洁,最直 接的遍历数组的语法支持map和Set对象遍历
- 缺点:
- 不适用于处理原有的原生对象(原生对象是一个子集,包含一些在运动 过程中动态创建的对象)
- 优点:
16.Promise
Promise对象是CommonJS工作组提出的一种规范,每一个异步任务返回一个Promise对象,改对象有一个then方法,允许指定回调函数;
用同步编程的方式来编写异步代码,保存线性的代码逻辑,极大的降低了代码耦合性而提高了程序的可扩展性。
romise的状态,实例化,捕错,异步方法?
- Promise共有三种状态,等待(pending),已完成(resolved,又称fulfilled),已拒绝(rejected);
- then方法(实例的方法)接收两个参数,第一个参数是成功的回调(pending–>fulfilled调用),第二个参数是失败的回调(pending–>rejected调用),then可以接受另一个promise传入,也接受一个”类then”的对象或方法,即thenable对象;
- catch(实例的方法)相当于.then(null,rejection),当then中没有传入rejection时,错误会冒泡进入catch函数中,若传入rejection则错误会被rejection捕获,而且不会进入catch,此外,then中的回调函数中发生的错误只会在下一级的then中被不会,不会影响promise的状态.
- all方法(构造函数Promise的方法)提供了执行异步操作的功能,all接收一个数组,数组参数为需要执行异步操作的所有方法,里面的值最终都算返回Promise对象,数组内异步操作都执行完毕之后才会进入到then里面.
- race方法(构造函数Promise的方法)与all方法相反,谁先执行完毕谁先进入race的回调,之后的将不再进入race的回调.
- Promise.none//所有promise被拒绝即完成,
- Promise.any//一个promise被完成即完成,
- Promise.first//第一个promise完成,忽略后续拒绝和完成,
- Promise.last//和first相反
- Promise回调链,promise能够在回调函数里面使用return和throw,所以在then中可以return出一个promise对象或者其他值,也可以throw出一个错误对象,如果没有return ,将默认返回undefined,之后的then中的回调参数接收到的将是undefined;
Promise的优缺点? - 优点:
- 将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数,避免了毁掉地狱;
- promise对象提供了统一的接口,使得异步操作更加容易;
- 缺点:
- promise无法取消,一旦新建就会立刻执行,无法中途取消;
- 若果不设置回调函数,promise内部抛出的错误,不会反映到外部;
- 处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是完成)
Promise 中reject 和 catch 处理上有什么区别 - reject是用来抛出异常,catch(相当于.then(null,rejection))是用来处理异常;
- reject是Promise 的方法,而 catch 是 Promise 实例的方法;
- reject后的东西,一定会进入then中的第二个回调,如果then中没有写第二个回调,会进入catch;网络异常(比如断网),会直接进入catch而不会进入then的第二个回调
三个promise,A,B,C串行执行;
A.then(B).then(B).then(C).catch(...) //promise
(async ()=> {await A();await B();await C();})() //async/await
17.this指向问题
- 普通函数调用,this 指向window(默认绑定);
- 构造函数调用,this 指向实例对象(new);
- 对象方法调用,this 指向该方法所属的对象(隐式绑定);
- 事件绑定中调用,this 指向绑定事件的对象;
- 定时器函数中调用,this 指向window;
- 箭头函数,this指向父作用域的this,不是调用时的this
18.箭头函数
箭头函数的this永远指向其父作用域,任何方法都改变不了,包括call,apply,bind。
箭头函数不能作为构造函数,不能使用new
19.Class
20.JS的new操作符做了哪些事情
- new操作符创建了一个空对象,这个对象原型指向构造函数的prototype;
- 执行构造函数;
- 返回对象(如果函数没有返回其他对象,则返回新对象)
21.深拷贝和浅拷贝
- 深拷贝:基本数据类型 栈内存 内存空间
-
- 循环遍历递归
-
- JSON对象的parse和stringify
-
- 浅拷贝:引用数据类型 堆内存 指向地址
- Object.assign()
22.String与toString的区别
- toString()是各种类型数据的方法,null和undefiend类型没有toString()方法
- String()转型函数,始终会返回表示相应类型的字符串,其使用时会判断类型数据是否有toString()方法,有则使用toString()方法进行返回,如果是null和undefiend则返回null和unde
- toString()无法转换null和undifiend类型
23.函数A继承函数B的方法(变量继承使用B(){A.call(this)})
- B.prototype = A.prototype(地址相同)
- B.prototype = new A({})(函数和声明的变量都赋值了)
- C(){};C.prototype = A.prototype;B.prototype = new C()() (地址不同,也不继承不需要属性)
- for(var key in A.prototype){ B.prototype[key] = A.prototype[key] }
24.创建一个原型不为object的对象
Object.create(null,{value:1}) // Object.prototype.__proto__=null
other
1.EventLoop(事件循环|事件轮询)
- Macrotask:主程序,setTimeout,setInterval,setImmediate,I/O,UIrendering;
- Microtasks:process.nextTick,Promise.then,Object.observe,MutationObserver;
-
在javascript中任务执行时,同步任务会交由主线程来执行,其余任务交由其他模块对应线程来执行,模块线程执行完后将对应结 果放至任务队列中供主线程提取结果,主线程在执行完同步任务后从任务队列中拿出任务执行结果;任务队列分为macrotasks和microtasks,在任务队列中,每执行一个macrotask任务,会将其对应的microtask所有任务执行完毕,然后再执行下一个macrotasks与其对应的microtasks,依次循环,这种循环执行的方式被称为事件循环或事件轮询;
补充:了解调用任务的API,schedule()在当前tick末尾添加任务,job loop可无限循环
2.捕获和冒泡的过程
- 3个事件阶段,依次是捕获阶段、目标阶段、冒泡阶段
- 捕获阶段:在事件对象到达事件目标之前,事件对象必须从window经过目 标的祖先节点传播到事件目标。这个阶段被我们称之为捕获阶段。在这个阶段注册的事件监听器在事件到达其目标前必须先处理事件。
- 目标阶段:事件对象到达其事件目标。 这个阶段被我们称为目标阶段。一旦事件对象到达事件目标,该阶段的事件监听器就要对它进行处理。如果一个事件对象类型被标志为不能冒泡。那么对应的事件对象在到达此阶段时就会终止传播。
- 冒泡阶段:事件对象以一个与捕获阶段相反的方向从事件目标传播经过其祖先节点传播到window。这个阶段被称之为冒泡阶段。在此阶段注册的事件监听器会对相应的冒泡事件进行处理。
3.防止冒泡和捕获
- w3c的方法是e.stopPropagation(),IE则是使用e.cancelBubble = true
4.DOM结构优化
- 减少DOM访问次数
- 多次访问同一DOM,应该用局部变量缓存该DOM
- 尽可能使用querySelector,而不是使用获取HTML集合的API
- 注意重排和重绘
- 使用事件委托,减少绑定事件的数量
5.浏览器缓存
- 客户端本地存储 webstorge
- 特定的域名下 cookie
6.sessionStorage和localStorage的区别
sessionStorage用于本地存储一个会话(session)中的数据,这些数据只有在同一个会话中的页面才能访问并且当会话结束后数据也随之销毁。
因此sessionStorage不是一种持久化的本地存储,仅仅是会话级别的存储。而localStorage用于持久化的本地存储,除非主动删除数据,
否则数据是永远不会过期的。
7.前端项目性能优化
使用精灵图/css,js文件的压缩打包/图片懒加载(减少首屏请求次数)/audio,video的preload:none/代码优化
- 代码优化:
- 减少DOM操作,用变量缓存DOM元素,减少DOM重排,重绘
- 代码异步编写,减少同步代码阻塞后续执行
- css选择器优化,多使用使用class选择器,减少标签选择器的使用,减少使用id选择器,减少选择器前缀(选择器从右向左查找,前缀多,查询时间长)
- 避免CSS表达式
- 减少冗余代码,提高复用率,“高内聚低耦合”
- 避免使用eval(),执行消耗大,代码压缩后容易出现代码执行错话问题
- 减少闭包使用(占用内存,内存泄漏)
- 事件委托
- 使用css3动画代替js动画
- 避免一次循环过多数据,避免while导致的死循环
- CSS放在header中,JS放在body尾部(先呈现页面,再让用户执行操作)
- 在CSS中减少对滤镜的使用
8.http工作过程:
- DNS解析
- TCP连接
- 发送请求
- 接收请求
- 断开连接
- 附:三次握手
- B确认自己可以接受到A的报文段
- A确认B可以接收到自己发的报文段,并且自己可以接受到B的报文段
- B确认A可以接收到自己发送的报文段
Vue模块
1.MVVM模式
- MVVM即Model-View-ViewModel的简写。 数据模型-视图-视图模型
- 数据模型(Model)指的是数据层。
- 视图(View)指的是所看到的页面,视图层。
视图模型(ViewModel)是mvvm模式的核心,它是连接view和model的桥梁
一是将数据模型(Model)转化成视图(View),即将后端传递的数据转化成所看到的页面。 实现的方式是:数据绑定。
二是将视图(View)转化成数据模型(Model),即将所看到的页面转化成后端的数据。 实现的方式是:DOM 事件监听。
这两个方向都实现的,我们称之为数据的双向绑定。
2.MVC和MVVM的区别
- MVC是DOM操作 渲染效率低
- MVVM通过监听数据的变化,响应到页面上
3.封装vue 组件的过程
首先,组件可以提升整个项目的开发效率。能够把页面抽象成多个相对独立的模块,解决了我们传统项目开发:效率低、难维护、复用性等问题。
然后,使用Vue.extend方法创建一个组件,然后使用Vue.component方法注册组件。子组件需要数据,可以在props中接受定义。而子组件修改好数据 后,想把数据传递给父组件。可以采用emit方法。
4.组件间的传值(通信)
- props+emit
父传子 方法名=参数 props:[方法名]
子传父 this.$emit(方法名,参数) @方法名=函数名 - Vuex this.$store.state.参数
- EventBus
vue.prototype.EventBus=new Vue() //Vue原型对象注入EventBus事件车
EventBus. e m i t ( 事件名 , 参数 ) / / A 组件中触发事件车对应函数 , 进行参数传递 E v e n t B u s . emit(事件名,参数) //A组件中触发事件车对应函数,进行参数传递 EventBus. emit(事件名,参数)//A组件中触发事件车对应函数,进行参数传递EventBus.on(事件名,事件处理函数)) //B组件设置事件以及事件处理函数
5.动态路由
router-link to=路径+参数
this.router.push(路径+参数)
this.$route.query.参数 地址栏?后的参数
this.$route.params.参数 地址栏/后的参数
6.路由模式
hash 地址栏有个#号 更改url不会重新加载页面 单页面
history URL跳转而无须重新加载页面 刷新页面会造成页面丢失需要前后端配置重定向
7.虚拟DOM树
扫描真实DOM树,提取出可能发生改变的元素组成一个新的DOM树
8.生命周期
- Vue生命周期的四个阶段 8个钩子函数
- beforeCreated / create 创建前/后 -------- 创建模型数据和响应系统
- beforeCreated:挂在元素$el:undefined 数据data:undefined
- Created: 挂在元素$el:undefined 数据data:{…}
- beforeMount / Mounted 载入前/后 -------- 创建虚拟DOM 并生成真实DOM
- Vue实例/组件首次加载完成/可以发送ajax请求/也可以操作DOM元素
- beforeMount: 挂载元素$el undefined 数据data {…}
- Mounted: 挂载元素$el DOM 数据data{…}
- beforeUpdate / Updated 更新前/后 ------- 监听数据与视图的变化
- beforeDestroy / Destroyed销毁前/后 ------- 销毁实例/销毁定时器
- beforeCreated / create 创建前/后 -------- 创建模型数据和响应系统
- 父子组件生命周期次序:
- 渲染: 父BC-父C-父BM-子BC-子C-子BM-子M-父M
- 更新: 父BU-子BU-子U-父U
- 销毁: 父BD-子BD-子D-子D
9.Vue中的路由守卫(vue-Router的方法)
- 守卫分类:
- 全局守卫:
- router.beforeEach(全局前置守卫)
- router.beforeResolve(全局解析)/导航确认前,所有组件内守卫和异步路由被解析后调用
- router.afterEach(全局后置钩子)
- 路由独守卫:
- beforeEnter:(to,form,next)=>{}
- 组件内守卫:
- beforeRouteEnter(to,from,next)=>{//不能使用this获取组件实例,实例未创建}
- beforeRouteUpdate(to,from,next)=>{//路由改变但是该组件被复用时调用}
- beforeRouteLeave(to,from,next)=>{//导航离开组件的对应路由时调用}
- 全局守卫:
- 完整的路由解析流程
- 1.导航被触发.
- 2.在失活的组件里调用beforeRouteLeave 守卫;
- 3.调用全局的 beforeEach 守卫;
- 4.在重用的组件里调用boforeRouteUpdate守卫;
- 5.在路由配置里调用boforeEnter.
- 6.解析异步路由;
- 7.在被激活的组件里调用boforeRouteEnter;
- 8.调用全局的beforeResolve 守卫;
- 9.导航被确认;
- 10.调用全局的 afterEach 钩子;
- 11.触发DOM更新;
- 12.调用beforeRouteEnter 守卫中传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传入
10.v-model双向绑定
v-model本质上是:value和v-on的结合体,就是绑定他的value,通过v-on触发,从而更新数据.
双向绑定得的实现主要依赖于Object.defineProperty(),通过这个函数可以监听到getter和setter事件.其中observer是最主要的部分,用 Object.defineProperty来实现数据的劫持,然后用他的set,get方法来通知订阅者,触发update方法,从而实现更新视图;
11.watch 和 computed
- 计算属性 computed 支持缓存,只有依赖数据发生改变,才会重新进行计算,不支持异步
- 监听属性 watch 不支持缓存,数据变化直接会触发相应的操作,支持异步
12.v-show和v-if指令的共同点和不同点?
- v-show指令是通过修改元素的 CSS属性display让其显示或者隐藏
- v-if指令是直接销毁和重建DOM达到让元素显示和隐藏的效果
13.This.$nextTick()原理
使用This.$nextTick()在DOM更新完毕之后基于更新后的数据执行一些操作,vue的DOM更新是异步执行的(将异步任务方法加入异步队列中,然后尝试使用原生的promise.then,MutatioinObserver,setImmediate,如果环境不支持则会采用setTimeout(fn,0),主程序在数据执行完之后执行DOM的异步更新),所以在同一个函数体内改变数据后想立马使用更新后的数据就需要使用this.$nextTick()来基于更新后的DOM执行操作,在JS的事件循环中,DOM更新属于宏观任务队列中的任务,process.nextTick属于微观任务队列中优先级最高的任务,vue中的this.$nextTick(callback)将其放到DOM更新完后的微任务队列的第一位进行执行
14.keep-alive的作用
组件缓存
在项目中,难免会有列表页面或者搜索结果列表页面,点击某个结果之后,返回回来时,如果不对结果页面进行缓存,那么返回列表页面的时候会回到初始 状态,但是我们想要的结果是返回时这个页面还是之前搜索的结果列表,这时候就需要用到vue的keep-alive技术了.
15.Vuex
Vuex是一个专为Vue开发的应用程序的状态管理模式,它采用集中式存储管理应用的 所有组件的状态(单一状态树管理),并以相应的规则保证状态以一种可预测的方式发生变化;
核心概念:
Store:要使用Vuex,我们要创建一个实例 store ,我们称之为仓库,利用这个仓库 store来对我们的状态进行管理
- State:Vuex 使用单一状态树,用一个对象State包含了整个应用层级的所有状态,你可以理解为这些状态就是一堆全局变量和数据
- Getter:当需要从state中派生出一些状态的时候,就会使用到getters,你可以将 getters 理解state的计算属性。
- Mutation:Vuex相比传统的全局变量有两个优势,其中一个是Vuex中的状态不能随意修改,要修改必要按照Vuex提供的方式才能修改
- Action: Action 类似于 mutation,不同在于:
- Action 提交的是 mutation,而不是直接变更状态。
- Action 可以包含任意异步操作,通过 store.dispatch 方法触发
- Module:状态模块化管理使用
场景有:单页应用中,组件之间的状态。音乐播放、登录状态、加入购物车
16.axios有哪些常用方法
- axios.get(url[, config]) //查询
- axios.delete(url[, config]) //删除
- axios.post(url[, data[, config]]) //添加
- axios.put(url[, data[, config]]) //更新
- axios.create([config]) //创建实例
- axios.interceptors.request.use(function(config){…}, function(error){…}) //请求拦截
- axios.interceptors.response.use(function(response){…}, function(error){…}) //响应拦截
- axios.interceptors.request.eject(此处为变量保存拦截实例) //移除拦截
- axios.cancellToken //取消请求,config中添加
17.Vue3.0
- 绑定原理:ES6 的Proxy代理对象,proxy在目标对象的外层搭建了一层拦截,外界对目标对象的某些操作,必须通过拦截,
- 对象内部所有属性被自动监视,后添加的属性一旦进入对象就被自动监视
- V-if优先级大于V-for
- 只能使用普通函数创建组件
- 异步组件定义方法修改,
- 新增事件接收emits属性,用于父子组件间事件传递与触发