URL解析->DNS查询->资源请求->浏览器解析
url解析:协议 域名+端口 路径 参数 哈希
DNS查询:dns缓存表
资源请求:三次握手四次挥手
浏览器解析:
- 1)浏览器根据深度遍历的方式把html节点遍历成dom 树
- 2)将css解析成CSS DOM树
- 3)将dom树和CSS DOM树构造成render树
- 4)JS根据得到的render树 计算所有节点在屏幕中的位置,进行布局(回流)
- 5)遍历render树并调用硬件API绘制所有节点(重绘)
图片引用来自https://img2018.cnblogs.com/blog/1308525/201901/1308525-20190113115419142-478609043.png
当一个元素接收到事件的时候,会把他接受到的所有传播给他的父级;一直到 window 为事件冒泡(该发生还是会发生)
- event.stopPropagation();
- event.preventDefault();
- return false;
DOM事件流"规定的事件流包括三个阶段:
- 1,事件捕获阶段。不断往下查找是哪个元素发出的事件;
- 2,处于目标阶段。找到该元素;
- 3,事件冒泡阶段。事件不断往上冒泡执行;
alt是代替图片的文字,图片不能显示时会显示alt,title是鼠标指上去时的解释的文字
web语义化的目的是提高开发者对web代码的可读性。比如header就是指头,food就是脚;
盒模型的组成,由里向外content, padding, border, margin.
在IE盒子模型中,width表示content+padding+border这三个部分的宽度
在标准的盒子模型中,width指content部分的宽度
特点:可以和其他元素保持在同一行,不可以自动换行,但不能设置宽高;
可以padding上下左右,不能margin上下;
a,span,strong,u(下划线),em(强调),i(斜体),sub(下标),sup(上标)
特点:不可以和其他元素保持在同一行(独占一行),可以自动换行,能设置宽高
div,p,h1-h6,ul,li,dl,dt,dd
特点:可以和其他元素保持在在一行,还能能设置宽高
常见标签:textarea,input,img,button
vue有8个生命钩子,分别为创建前后、加载前后、更新前后、销毁前后。
生命周期 | 作用 |
---|---|
beforeCreate | new Vue后没有data没有el没有methods |
create | 这个阶段data已经加载出来,有data没有el,一般可以做初始化数据的获取 |
beforeMount | 虚拟DOM已经创建完成,但是还没挂载上去,(有data,有el),得不到具体的DOM元素 |
mount | 数据和DOM都已经被渲染出来了 |
beforeUpdate | 这时数据已经更新,但是页面上的数据还是旧的; |
Update | 这时页面上的数据也是更新的 |
beforeDestroy | 可以做alert,“你确定要销毁这个XXX吗?” |
Destroy | 当前组件已被删除,销毁监听事件,组件、事件、子实例也被销毁。 |
字段 | 作用 |
---|---|
name | cookie的名称 |
value | cookie的值 |
Size | cookie大小 |
domain | 可以访问此cookie的域名 |
path | 可以访问此cookie的页面路径。 比如domain是abc.com,path是/test,那么只有/test路径下的页面可以读取此cookie。 |
expires/Max-Age | 字段为此cookie超时时间。若设置其值为一个时间,那么当到达此时间后,此cookie失效。不设置的话默认值是Session,意思是cookie会和session一起失效。当浏览器关闭(不是浏览器标签页,而是整个浏览器) 后,此cookie失效。 |
http | cookie的httponly属性。若此属性为true,则只有在http请求头中会带有此cookie的信息,而不能通过document.cookie来访问此cookie。 |
secure | 设置是否只能通过https来传递此条cookie |
cookie:
默认时间:关闭浏览器失效;
设置时间:设置的cookie过期时间之前一直有效,即使窗口关闭或浏览器关闭。大小只有4kb;
sessionStorage: 仅在当前会话下有效,关闭页面或浏览器后被清除。存放数据大小为>=5MB,而且它仅在客户端(即浏览器)中保存,不参与和服务器的通信。
localStorage: 生命周期是永久,除非主动清除localStorage信息,否则这些信息将永远存在。存放数据大小为>=5MB,而且它仅在客户端(即浏览器)中保存,不参与和服务器的通信。
cookie:针对cookie所存在的攻击:Cookie欺骗,Cookie截获;session的安全性大于cookie。
原因:
sessionID存储在cookie中,若要攻破session首先要攻破cookie;
sessionID是加密的
sessionID是要有人登录,或者启动session_start才会有,所以攻破cookie也不一定能得到sessionID;
第二次启动session_start后,前一次的sessionID就是失效了,session过期后,sessionID也随之失效;
vue是通过Object.defineProperty()来实现数据劫持的,通过get和set操作数据。这一步已经实现简单的双向绑定了。但是效率低。
为了解决效率低下问题,vue数据双向绑定是通过数据劫持结合发布者-订阅者模式的方式来实现。
1.实现一个监听器Observer,用来劫持并监听所有属性,如果有变动的,就通知订阅者。
2.实现一个订阅者Watcher,可以收到属性的变化通知并执行相应的函数,从而更新视图。
3.实现一个解析器Compile,可以扫描和解析每个节点的相关指令,并根据初始化模板数据以及初始化相应的订阅器。
详细实现过程:https://www.cnblogs.com/chenhuichao/p/10818396.html
相同点:都能隐藏元素。
不同点:
display:none --> 不为隐藏对象保留内存,在页面上消失,通俗讲看不见也摸不着;
visible:hidden --> 只是在页面上看不见,内存并未消失,看不见摸得着;
方案1:viewport + rem实现:
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
方案2:
做多个
none : 元素消失,看不见摸不着;
inline : 行内元素 元素会在一行内显示,超出屏幕宽度自动换行,不能设置宽度和高度,元素的宽度和高度只能是靠元素内的内容撑开。
block : 块级元素 会独占一行,如果不设置宽度,其宽度会自动填满父元素的宽度,可以设置宽高,即使设置了宽度,小于父元素的宽度,块级元素也会独占一行。
inline-block : 行内块元素 与行内元素一样可以再一行内显示,而且可以设置宽高,可以设置margin和padding;
list-item : 列表元素;
table : 会作为块级表格来显示(类似于table),表格前后带有换行符;
inline-table : 会作为内联表格来显示(类似于table),表格前后没有换行符;
flex : 多栏多列布局,自适应布局;
inherit : 继承,如果元素的某些属性没有进行设置,有些是会有默认值的,有些是会继承的。
如果是对象,那么构建一个组件的时候data就是公开类型,多个组件传参就会数据混淆。
所以通过return 返回对象的拷贝,从而开辟一个新的空间地址,致使每个实例都有自己独立的对象。
深拷贝:
内存地址相互独立,每条数据之间不相互影响。
浅拷贝:
引用内存地址,修改新赋值变量,旧变量也会发生改变。
相同点:
call、apply、bind的作用是改变函数运行时this的指向
不同点:
bind和apply,call的区别在于,bind返回一个方法,用于后面调用,apply和call会直接执行
不同名称 | call | applay | bind |
---|---|---|---|
参数不同 | call(对象,参数1,参数2,…) | applay(对象,[参数1,参数2,…]) | bind(对象,参数1,参数2,…) |
执行时间 | 当场执行 | 当场执行 | 返回一个方法,用于后面调用 |
- CSS 中伪类一直用 : 表示,如 :hover, :active 等
- 素在CSS1中已存在,当时语法是用 : 表示,如 :before 和 :after
- 在CSS3中修订,伪元素用 :: 表示,如 ::before 和 ::after,以此区分伪元素和伪类
- 低版本IE对双冒号不兼容,开发者为了兼容性各浏览器,继续使使用 :after 这种老语法表示伪元素
- 所述:::before 是 CSS3 中写伪元素的新语法; :after 是 CSS1 中存在的、兼容IE的老语法
opacity 子元素颜色会被影响,即变相的被继承。rgba(r,g,b,a)不会
什么叫闭包?
一个function内的function
(一)
用闭包主要是为了设计私有的方法和变量。
闭包的优点是可以避免全局变量的污染,缺点是闭包会常驻>存,会增大内存使用量,使用不当很容易造成内存泄露。
包有三个特性:
.函数嵌套函数
.函数内部可以引用外部的参数和变量
.参数和变量不会被垃圾回收机制回收
GET和POST本质上两者没有任何区别。他们都是HTTP协议中的请求方法。底层实现都是基于TCP/IP协议。
发送方式:get通过地址栏传输,post通过报文传输。
get请求数据接在url后面,post请求数据通过send方法传递
get传递的数据会比较少,post没有限制
get传递的数据会暴露出来
GET产生一个TCP数据包;POST产生两个TCP数据包
1.全局变量:如未声明变量
2.闭包:闭包可以读取函数内部的变量,然后让这些变量始终保存在内存中。如果在使用结束后没有将局部变量清除,就可能导致内存泄露。
3.事件监听:对同一个事件重复监听,但是忘记移除,会导致内存泄露。
4.其他原因
console.log打印的对象不能被垃圾回收,可能会导致内存泄露。
setInterval也可能会导致内存泄露。
深圳pmst公司笔试题
1. var a = /678/,
b = /678/;
console.log(a==b) /*false*/
console.log(a===b) /*false*/
2. var a = {
}, b = Object.prototype;
[a.prototype === b, Object.getPrototypeOf(a) === b]
/*结果 = [false, true]*/
3. javascript定义var a='40', b=7,则执行a%b会得到什么?
/*结果 = 5*/
4. console.log(([])?true:false)
console.log(([]==false)?true:false)
console.log(({
}==false)?true:false)
/*结果: true、true、false*/
5. var msg = 'hello'
for(var i=0;i<10;i++){
var msg = 'hello'+i*2+i
//9*2+9='hello18'+9
}
console.log(msg)
/*结果: hello189*/
6. console.log([typeof null, null instanceof Object])
/*结果:“object”, false */
因为0.1等小数在底层计算转换二进制时是无线的,所以到最后是0.2999999.
- 引入math.js
- (0.1 + 0.2).toFixed(10) == 0.3
- 记录小数点后个数,使用增大倍数到整数,按小数点个数插入小数点
子组件先完成渲染。父组件最先开始渲染
父beforeCreate->父create->父boforeMount->子beforeCreate->子create->子beforeMount->子Mount->夫Mount
application/json
(几个常见的)
属性 | 例如 | 作用 |
---|---|---|
Accept | text/html | 代表浏览器可以接受服务器回发的类型为 text/html |
Accept-Encoding | zh-CN,zh | 浏览器申明自己接收的编码方法,通常指定压缩方法,是否支持压缩,支持什么压缩方法 |
Accept-Language | Accept-Language: en-us | 浏览器申明自己接收的语言。 |
Referer | url格式 | 告诉服务器我是从哪个页面链接过来的,服务器籍此可以获得一些信息用于处理。 |
User-Agent | 略 | 告诉HTTP服务器, 客户端使用的操作系统和浏览器的名称和版本. |
//请求拦截
http.interceptors.request.use(config=>{
// 这儿一般涉及到用户验证
//使用token进行用户权限认证,需要在请求的header中添加token信息进行验证
let t = cookies.get('t')
if (t) {
config.headers.t = t
} else {
router.replace({
path: '/login'})
}
return config
},
err => {
return Promise.reject(err)
})
//响应拦截
http.interceptors.response.use(response=>{
// 这儿一般涉及到用户cookie过期
console.log(response)
return response
},err =>{
if (err.response) {
switch (err.response.status) {
case 401:
// 这里写清除token的代码
router.replace({
path: 'login',
query: {
redirect: router.currentRoute.fullPath} // 登录成功后跳入浏览的当前页面
})
}
})
7种
- null (复杂类型)
- undefined (复杂类型)
- boolean (基本类型)
- number (基本类型)
- string(基本类型)
- 引用类型(object、array、function)
- symbol
6种
名称 | 版本 |
---|---|
var | ES5、ES6 |
let | ES5、ES6 |
const | ES5、ES6 |
function | ES5、ES6 |
import | ES6 |
class | ES6 |
名称 | 展示 | 作用 |
---|---|---|
块作用域 | {} | let 允许创建块级作用域,ES6 推荐在函数中使用 let 定义变量,而非 var |
箭头函数 | ()=> | 箭头函数就是函数的一种简写形式,使用括号包裹参数,跟随一个 =>,紧接着是函数体 |
函数参数默认值 | 略 | ES6 中允许你对函数参数设置默认值 |
展开操作符 | … | […arr] |
模板语法 | `` | `Hi ${user}!` |
对象超类 | super() | |
二进制和八进制字面量 | 0o、0O | 通过在数字前面添加 0o 或者 0O 即可将其转换为二进制值 |
for of和for in | for of 、for in | for…of 用于遍历一个迭代器用数组;for…in 用来遍历对象中的属性; |
Map 和 WeakMap | 在 Map 中,任何类型都可以作为对象的 key;WeakMap 的所有 key 必须是对象 | |
Set 和 WeakSet | Set 对象是一组不重复的值,重复的值将被忽略,值类型可以是原始类型和引用类型 | |
类 | class | 创建对象,可以使用extends 继承 |
Symbol | ES6 中提出 symbol 的目的是为了生成一个唯一的标识符 | |
迭代器 | Iterators | 它提供了 next() 函数来遍历一个序列、ES6 中可以通过 Symbol.iterator 给对象设置默认的遍历器 |
Generators | ||
Promises | promise对象代表一个异步操作,有三种状态:Pending(进行中)、Resolved(已完成)和Rejected(已失败) |
回流必定重绘
回流
当render tree中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建。这就称为回流(reflow),每个页面至少需要一次回流,就是在页面第一次加载的时候,这时候是一定会发生回流的,因为要构建render tree。
在回流的时候,浏览器会使渲染树中受到影响的部分失效,并重新构造这部分渲染树,完成回流后,浏览器会重新绘制受影响的部分到屏幕中,该过程成为重绘。
重绘
当render tree中的一些元素需要更新属性,而这些属性只是影响元素的外观,风格,而不会影响布局的,比如background-color。则就叫称为重绘。
区别:
回流必将引起重绘,而重绘不一定会引起回流。比如:只有颜色改变的时候就只会发生重绘而不会引起回流
当页面布局和几何属性改变时就需要回流
比如:添加或者删除可见的DOM元素,元素位置改变,元素尺寸改变——边距、填充、边框、宽度和高度,内容改变
如何优化?
- 尽量使用transform 代替margin-top
- 用opacity(透明) 代替 visibility(隐藏)
- 不要使用table布局,可能很小的一个小改动会造成整个 table 的重新布局
- 对于频繁变化的元素应该为其加一个 transform 属性,对于视频使用video 标签
- …
beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave
每个生命钩子(周期)都有三个参数:
- to: Route: 即将要进入的目标 路由对象
- from: Route: 当前导航正要离开的路由
- next: Function: 一定要调用该方法来 resolve 这个钩子
应用场景:浏览器滚动条监听、输入监听、鼠标移动监听等…
防抖:
所谓防抖,就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。
function debounce(func, wait) {
let timeout;
return function () {
let context = this;
let args = arguments;
if (timeout) clearTimeout(timeout);
timeout = setTimeout(() => {
func.apply(context, args)
}, wait);
}
}
content.onmousemove = debounce(count,1000);
节流:
所谓节流,就是指连续触发事件但是在 n 秒中只执行一次函数。节流会稀释函数的执行频率。
function throttle(func, wait) {
let timeout;
return function() {
let context = this;
let args = arguments;
if (!timeout) {
timeout = setTimeout(() => {
timeout = null;
func.apply(context, args)
}, wait)
}
}
}
content.onmousemove = throttle(count,1000);
主任务
宏任务setTimeout()
微任务.then()
- 根组件实例:8个 (beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy、destroyed)
- 组件实例:8个 (beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy、destroyed)
- 全局路由钩子:2个 (beforeEach、afterEach)
- 组件路由钩子:3个 (beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave)
- 指令的周期: 5个 (bind、inserted、update、componentUpdated、unbind)
- beforeRouteEnter的next所对应的周期
- nextTick所对应的周期
<configuration>
<system.webServer>
<!-- 设定网站服务器以指定预设兼容性模式 Lionden -->
<httpProtocol>
<customHeaders>
<clear />
<add name="X-UA-Compatible" value="IE=EmulateIE7" />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>