1. 浏览器解析
- 用户输入网址
- 对输入的URL进行语法解析,如果网址不合法会抛出错误
- 查看本地cache,网址被分段解析后,浏览器首先在本地缓存查询cache,如果cache被标明是最新的则直接使用缓存内容。
- dns解析,向dns服务或服务器查询域名所对应的IP地址
- 请求连接,tcp三次握手,连接服务器
- 发送http请求,向服务器发送请求
- 接收服务器响应,服务器发回一个HTML响应,浏览器开始显示HTML,浏览器发送获取嵌入在HTML中的对象
- 断开连接
- 写cache,将可以缓存的数据写入cache中
- 大概:用户输入网址——浏览器查找IP地址——发送HTTP请求——服务器处理请求并响应——服务器发回HTML响应——浏览器开始解析HTML——浏览器发送请求获取HTML中内嵌的对象,如CSS/JS/图片等资源——浏览器展示完整页面
浏览器解析html响应过程
- 加载-解析-渲染(加载过程进行解析渲染)
- 浏览器自上而下加载html代码,发现link引用外部css文件时,请求css文件,等待服务器响应(异步,不阻塞DOM加载和解析,但会阻塞页面渲染),服务器响应,浏览器解析,浏览器拿到css文件,可以开始渲染页面;发现img时,请求(异步),遇到js外部文件加载(同步),阻塞页面后续的内容的加载以及解析
- 解析页面标签生成DOM树,解析css资源生成CCSOM树,Javascript 脚本文件加载后, 通过 DOM API 和 CSSOM API 来操作 DOM Tree 和 CSS Rule Tree
- 浏览器引擎通过 DOM Tree 和 CSS Rule Tree 构建 Rendering Tree(渲染树),下一步layout,就是计算出每个节点在屏幕中的位置。 之后绘制rendering tree
- 总结一个版本:
- 浏览器开始解析HTML代码(自上向下),发现link引用外部css文件,请求css文件,服务器响应,浏览器解析;
- 浏览器继续载入html中<body>部分的代码,并且CSS文件已经拿到手了,可以开始渲染页面了
- 当发现img标签时,发出请求,此时浏览器不会等待图片加载,而是继续渲染后面的代码;
- 服务器返回图片文件,由于图片占用了一定面积,影响了后面段落的排布,因此浏览器需要回过头来重新渲染这部分代码;
- 发现script-js脚本,载入后立马执行(不管HTML有没有被渲染),执行后会阻塞页面后续的内容包括页面的渲染、其它资源的下载)。原因:因为浏览器需要一个稳定的DOM树结构,而JS中很有可能有
代码直接改变了DOM树结构,比如使用 document.write 或
appendChild,甚至是直接使用的location.href进行跳转,浏览器为了防止出现JS修
改DOM树,需要重新构建DOM树的情况,所以 就会阻塞其他的下载和呈现。所以,js 死循环执行不完的话,页面也就别想呈现了,所以,建议将所有的script标签放到页面底部;- 假设js脚本中有
style.display=”none”
,执行后,浏览器需要重新渲染部分代码- 直至解析至
</html>
- 假若,浏览器点击某些功能改变样式,换了css外部样式,浏览器需要重新向服务器请求新的css文件,重新渲染页面
2. vue的生命周期
vue的生命周期是指从vue实例创建、运行、销毁的过程(开始创建、初始化数据、编译模板、挂载Dom、渲染→更新→渲染、卸载)
生命周期函数:
- 创建期间:
- beforeCreate():实例、组件通过new Vue() 创建出来之后会初始化事件和生命周期,然后就会执行beforeCreate钩子函数,这个时候,数据还没有挂载呢,只是一个空壳,无法访问到数据和真实的dom,一般不做操作
- created():挂载数据,绑定事件等等,然后执行created函数,这个时候已经可以使用到数据,也可以更改数据,在这里更改数据不会触发updated函数,在这里可以在渲染前倒数第二次更改数据的机会,不会触发其他的钩子函数,一般可以在这里做初始数据的获取(
要操作data中的数据和methods中的方法最早只能在created中
) - beforeMount():表示模板已经在内存中编辑完成,但尚未把模板内容渲染到页面中,在beforeMount执行的时候,页面中的元素还没有被真正的替换过来,只是之前写的一些模板字符串。在这里也可以更改数据,不会触发updated,在这里可以在渲染前最后一次更改数据的机会,不会触发其他的钩子函数
- mounted():表示内存中的模板已经真实的挂载到了页面中,用户可以看到渲染的页面,mounted是实例创建期间的最后一个生命周期函数,当执行完mounted,就表示实例已经被完全创建好了,此时,如果没有其他操作的话,这个实例就静静的躺在我们的内存中
- 运行期间:
- beforeUpdate():页面还没有被更新,此时data中的数据是最新的,但是界面上显示的还是旧数据,因为此时还没有重新渲染DOM节点
- updated():数据已经更改完成,执行时页面和data中的数据已经保持同步
- 销毁期间:
- beforeDestroy():当经过某种途径调用$destroy方法后,立即执行beforeDestroy,此时vue实例就已经从运行阶段进入销毁阶段,但是实例上的data、methods、以及过滤器,指令等都处于可用状态,一般在这里做一些善后工作,例如清除计时器、清除非指令绑定的事件等等
- destroyed():当执行时,组件已经完全销毁了,此时,组件中的所有数据、方法等都不可用了
3. 数组、字符串的常用方法
- 数组的常用方法 :
- toString():数组转为字符串(以逗号分隔)
- join():数组转为字符串,可以定义分隔符
- push():在数组末尾添加一个或多个元素,返回数组长度
- pop():在数组末尾删除最后一个元素,返回移除项
- shift():删除数组第一个元素,返回移除向项
- unshift():像数组首部添加一个或多个元素,返回新的长度
- splice():实现数组的删除、插入、替换,返回删除元素组成的数组
splice(index,length,item):表示从index开始,删除长度length个元素,插入item - concat():合并数组,
原数组不变
- slice():裁剪数组,
原数组不变
slice(start,[end]):如果有end下标,返回值不含结束位置 - sort():数组排序,默认从小到大
sort(function(a,b){ return a-b) } 从小到大
sort(function(a,b){ return b-a) } 从大到小 - reverse():反转数组
- forEach():遍历数组,没有返回值,元素组不变
forEach(function(item, index, a){} :a是数组本身 - map():对每个数组元素执行函数来创建新数组,不会对没有值的数组元素执行函数,不会更改原始数组
- some():检查某些数组值是否通过了测试,只要有一项满足条件,就会返回true
- filter():过滤,创建一个包含通过测试的数组元素的新数组,不改变原数组
- every():判断数组中每一项都是否满足条件,只有所有项都满足条件,才会返回true
- find():返回通过测试函数的第一个数组元素的值
- 字符串的常用方法:
- search():搜索特定值的字符串,并返回匹配的位置,可以用正则表达式
- slice():提取字符串,
slice(start, end):不包含结束位置 - substring():提取字符串
substring(start, end):不包含结束位置(无法接受负索引) - substr():提取字符串
substr(start,length):第二个参数是要提取的长度 - replace():替换字符串,默认地,replace() 只替换首个匹配;replace() 对大小写敏感;可以用正则表达式
- toUpperCase() | toLowerCase()
字符串大写|字符串小写 - concat():拼接字符串
- trim():删除字符串两端的空白符,IE8及其以下不支持
- charAt(index):返回字符串中指定下标(位置)的字符串
- charCodeAt(index):返回字符串中指定索引的字符 unicode 编码
- split():字符串转为数组
var str6 = "a,b,c,d,e";
console.log(str6.split(","));//["a", "b", "c", "d", "e"]以逗号分割
console.log(str6.split(" "));//["a,b,c,d,e"]数组长度为1 以空格分隔
console.log(str6.split("|"));//["a,b,c,d,e"] 以|分隔
console.log(str6.split(",",2));// ["a", "b"] 以逗号分隔,返回数量为2
var str7="Hello World!";
console.log(str7.split(" "));//["Hello", "World!"] 以空格分隔
console.log(str7.split(""));//["H", "e", "l", "l", "o", " ", "W", "o", "r", "l", "d", "!"]单个字符
- match():可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配。
4. cookie、sessionStorage、localStorage、session的区别
cookie、sessionStorage、localStorage的区别
cookie
:Web站点跟踪用户技术,指某些网站为了辨别用户身份,进行session跟踪而存储在用户本地终端上的数据sessionStorage
:将数据保存在session对象中。所谓session,是指用户在浏览某个网站时,从进入网站到浏览器关闭所经过的这段时间,也就是用户浏览这个网站所花费的时间。session对象可以用来保存在这段时间内所要求保存的任何数据。这些数据只有在同一会话中的页面才能访问,当用户关闭浏览器窗口后,数据会被删除localStorage
:将数据保存在客户端本地的硬件设备中,即使浏览器被关闭了,该数据任然存在,下次打开浏览器访问网站时任然可以继续使用区别
:
共同点:都是保存在浏览器端的,且同源的
不同:- cookie数据会在客户端和服务器之间来回传递,、sessionStorage和localStorae不会自动把数据发送给服务器,仅在本地存储
- cookie数据不能超过4K,、sessionStorage和localStorae虽然也有存储大小限制,但比cookie大得多,可以达到5M或更大
- cookie需要指定作用域,不可以跨域调用(在同源窗口都是共享的),sessionStorage不在不同的浏览器窗口中共湘,即使是同一页面;localStorae在所有同源窗口中都是共享的
- sessionStorage仅仅在当前浏览器窗口关闭之前有效;localStorae始终有效,窗口或浏览器关闭之后也一直保存;cookie只在设置cookie过期时间之前有效。
cookie和session的区别
cookie和session都是用来跟踪浏览器用户身份的会话方式。
- cookie数据存放在客户的浏览器上,session数据放在服务器上。
- cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗,考虑到安全应当使用session。
- session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性能方面,应当使用COOKIE。
- 单个cookie保存的数据不能超过4K,很多浏览器都限制nei一个站点最多保存20个cookie。
- 所以建议:将登陆信息等重要信息存放为SESSION;其他信息如果需要保留,可以放在COOKIE中
- session保存在服务器,客户端不知道其中的信息;cookie保存在客户端,服务器能够知道其中的信息。
- session中保存的是对象,cookie中保存的是字符串。
- session不能区分路径,同一个用户在访问一个网站期间,所有的session在任何一个地方都可以访问到。而cookie中如果设置了路径参数,那么同一个网站中不同路径下的cookie互相是访问不到的。
5. 盒子模型
盒子模型分为W3C标准模型和IE模型
- W3C标准模型(content-box):盒子的宽为:内容宽度+内边距宽度+边框+外边距宽度
- IE盒模型(border-box):盒子宽度为:内容宽度(content+padding+border)+外边距宽度
- 通过box-sizing设置
6. 原型和原型链
原型:
- 原型是Javascript中的继承的基础,JavaScript的继承就是基于原型的继承。
- 实例对象中
__proto__
属性,它是原型,也是一个对象,可以叫做原型对象 - 构造函数中有个
prototype
属性,它是原型,也是一个对象,可以叫做原型对象 - 实例对象的
__proto__
与构造函数的prototype
相等 - 实例对象的
__proto__
指向了构造函数的原型对象prototype
原型链:
- 实例对象、构造函数和原型对象之间的关系
- 构造函数的
prototype
指向他的原型对象 - 实例对象的
__proto__
指向构造函数的原型对象prototype
- 原型对象中的
constructor
指向他的构造函数
7. 数组去重
var arr=[1,4,6,2,1,4,a,a];
function deleteItem(arr){
for(var i=0;i<arr.length;i++){
if(arr.indexOf(arr[i])!=i){
arr.splice(i,1);
i--;
}
}
console.log(arr);
}
deleteItem(arr);
方法二:高性能,利用对象属性不会重复特性
function distinct(a, b) {
let arr = a.concat(b)
let result = []
let obj = {}
for (let i of arr) {
if (!obj[i]) {
result.push(i)
obj[i] = 1
}
}
return result
}
方法三:双重循环
方法四:先排序,判断相邻的两项是否相等
方法五:for…of实现循环
8. CSS选择器
id选择器,class选择器,标签选择器,通配符选择器,属性选择器,子代选择器,后代选择器,相邻选择器,伪类选择器
- 可继承属性:字体设置的都可以继承,color,font-size等等
- 不可继承属性:border、padding、margin、width等等
- 优先级:!important>style行内样式>id选择器>类选择器>标签选择器
css优先级
标签选择器:1
class选择器:10
id选择器:100
style行内样式:1000
9. 清除浮动
浮动:一个盒子使用了CSS float浮动属性,导致父级对象盒子不能被撑开。浮动的本质是实现文字环绕的
浮动的特性:
- 块级元素可以横排显示
- 行内元素可以设置宽度和高度
- 元素没有设置宽高时,宽度是撑开的宽
- 支持margin,不支持margin:auto
- 脱离文档流
清除浮动:
- 给父元素增加
overflow:hidden
“overflow:hidden”会触发BFC,BFC反过来决定了"height:auto"是如何计算的,即计算BFC的高度时,浮动元素也参与计算,因此此时父元素会自适应浮动元素的高度。所以呢,也可以设置"display:inline-block"、“position:absolute”、"float:left"来解决父元素高度坍塌的问题。因为凡是能创建一个BFC,就能达到包裹浮动子元素的效果。因此网上都说成“BFC能包裹浮动元素”.
.over-flow{
overflow: auto;
zoom: 1; //处理兼容性问题
}
- 使用伪元素
:after
或:before
可以给父元素的内容添加一个伪元素,可以用:before或者:after,然后内容为空,这样就不会占据位置,最后为伪元素加上“clear:both"来清除浮动。兼容问题:增加*zoom:1 - 在父级元素内的末尾加一个块级元素,添加
clear:both
- 父级添加高度
10. JS作用域、闭包
- 作用域:
作用域就是变量与函数的可访问范围,即作用域控制着变量与函数的可见性和生命周期。
js中的作用域分为全局作用域和局部作用域 - 作用域链:
作用域有上下级的关系,会在当前作用域中寻找变量,如果找不到会沿着创建时作用域链一直往上找,直到找到全局作用域 - 闭包:
在一个函数内部定义的另一个函数,当内部函数在包裹他的函数之外被执行时,就会形成闭包。同时内部函数仍然可以访问到包裹函数中的局部变量与函数。(闭包就是能够读取其他函数内部变量的函数)
闭包注意点:
内存消耗大、不能滥用,造成性能问题,在IE中可能造成内存泄漏,解决:手动释放变量
11. ajax中get、post的区别
get和post都是向服务器发送请求,只是发送机制不一样
- get请求会将参数跟在url后面进行传递,而post会将参数作为http请求得请求正文发送给服务器
- 发送的数据数量:get请求只能发送的数据最多4K,因为数据是在URL中发送的;post可以发送大量的数据,因为数据是在正文主件中发送的(在http中”GET方式提交的数据最多只能是1024字节”,Post传输的数据量大,可以达到2M。 )
- 安全性:get发送的数据不受保护,他是分开的,增加了漏洞和黑客攻击的风险;post发送的数据是安全的,它可以使用多种编码技术,这使其具有弹性
- get请求需注意缓存问题,post请求不需担心这个问题(get方式请求的数据会被浏览器缓存起来,因此其他人就可以从浏览器的历史记录中读取到这些数据,例如账号和密码等。某种情况下,get方式会带来严重的安全问题。而post方式相对来说就可以避免这些问题 )
- get主要是为了获取数据,post是更新或提交数据
12.jQuery的节点操作
- 查找结点
- 创建节点
$(html) - 插入节点
append
appendTo
prepend
prependTo
after
insertAfter
before
insertBefore - 删除节点
remove$("li").remove(".current");----$("li:eq(2)").remove();
empty:清空节点,能清空元素中的所有的文本和后代节点 - 复制节点
clone - 属性操作
attr:获取节点属性,设置节点样式
removeAttr:删除属性 - 样式操作
css
class:addClass、removeClass、toggleClass、hasClass
13. js中的同步异步
同步:需要排队等待,上一个任务完成之后才可以执行
异步:不需要等待
JS是一门单线程语言,所谓单线程就是需要排队等待,前一个任务结束之后,才可以执行本任务
- JS为什么是单线程的?
避免复杂性
js最初的目的是实现和用户的交互以及DOM操作,假若他不是单线程,它会带来复杂的问题,例如:他有两个线程,一个在某个节点上添加了内容,一个删除了这个节点,那么浏览器应该以哪个线程为主? - JS中为什么要加异步?
如果JS中不存在异步,只能自上而下执行,万一上一行解析时间很长,那么下面的代码就会被阻塞。导致了很差的用户体验
14. var、let、const的区别
- var声明的变量会挂载在window上,let和const不会
- var声明的变量存在变量提升,let和const不存在
- let和const声明形成块作用域
- 同一作用域下的let、const不可以声明同名变量,var可以
- 暂存死区
报错:在当前块作用域中,用let或const声明的变量,给a赋值10的时候,只会在当前作用域下查找,此时还没有声明,所以会报错a is not defined
var a = 100;
if(1){
a = 10;
let a = 1;
}
- const一旦申明必须赋值,不能用null占位,声明之后不可以修改,若声明的是复杂类型变量,可以修改
15. 跨域
跨域是指一个域下的文档或脚本试图去请求另一个域下的资源,这里跨域是广义的。我们通常所说的跨域是狭义的,是由浏览器同源策略限制的一类请求场景。
所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源。
1、 通过jsonp跨域 (缺点:只能实现get一种请求)
2、 document.domain + iframe跨域
3、 location.hash + iframe
4、 window.name + iframe跨域
5、 postMessage跨域
6、 跨域资源共享(CORS)
7、 nginx代理跨域
8、 nodejs中间件代理跨域
9、 WebSocket协议跨域
16. flex布局
给予容器控制内部元素高度和宽度的能力
flex-direction
flex-wrap
flex-flow
justify-content
align-items
align-content
17. 事件委托
事件本来是加在某些元素上的,然而却加到别人身上来做,完成这个事件。利用冒泡的原理,把事件加到父级上,触发执行效果
好处:
提高性能
新添加的元素也有事件
作用:
支持为同一个DOM元素注册多个同类型事件
可将事件分成事件捕获和事件冒泡机制
18. 继承
- 原型链继承
Per.prototype=new Person()
缺点:无法实现多继承 - 借用构造函数实现继承
借用call、apply实现继承
特点:复制父类的实例属性给子类,可以实现多继承
缺点:不能继承原型上的属性和方法 - 组合继承
原型链继承+构造函数继承 - 拷贝继承
- 原型式继承
- 构造函数+深拷贝
- 寄生组合继承
通过寄生方式,砍掉父类的实例属性,在调用两次父类的构造的时候,就不会初始化两次实例方法/属性
19. Promise
- Promise是一个构造函数,也是一个对象,可以通过new来创建一个实例,他保存着未来将要结束的事件
- 在promise上有两个函数:resolve()、reject()
- Promise表示一个异步操作,每当new一个实例时,实例就表示一个具体的异步操作,结果只有两种:成功、失败,只能使用回调函数将结果返回给调用者
- 在Promise构造函数prototype中有
.then
方法,可以在new出来的实例上使用.then
方法,预先
为这个Promise异步操作指定成功和失败的回调函数 只要一创建就会立即执行
:每当创建一个实例时,就会立即执行这个异步操作中的代码- 将Promise的异步操作定义为一个方法,就可以按需执行
- Promise有三种状态:pending进行中、fulfilled已成功、rejected已失败,任何其他操作都不能改变这个状态,这也是Promise的名字的由来
.catch
捕获异常
20. 前端优化
1、网络方面
- 减少HTTP请求
- 合并js文件
- 合并css文件
- 使用base64编码表示简单的图片
- 精灵图的使用css sprite
- 减少资源体积
- gzip压缩
- js混淆
- 图片压缩
- css压缩
- 缓存
- DNS缓存
- CDN部署与缓存
- http缓存
- 移动端优化
- 使用长cache,减少重定向
- 首屏优化,保证首屏加载数据小于14kb
- 不滥用web字体
2、渲染和DOM操作方面
- 优化网页渲染
- css放在头部,js放在底部或者异步
- DOM操作优化
- 避免在document上直接进行频繁的DOM操作
- 使用classname代替大量的内联样式修改
- 对于复杂的UI元素,设置position为absolute或fixed
- 尽量使用css动画
- 使用requestAnimationFrame代替setInterval操作
- 适当使用canvas
- 尽量减少css表达式的使用
- 使用事件代理
3、数据方面
- 图片加载处理
- 图片预加载
- 图片懒加载
- 首屏加载进度条显示
21. ES6
22. bootstrap的优点
23. H5、C3新增
H5:email、data、number、range、audio、video、header、footer、nav、aside、artical
C3:box-shadow、border-image、text-shadow、word-wrap
24. 打勾动画
25. HTTP、HTTPS
http是超文本传输协议,依靠TCP完成的可靠