前端面试复习要点

1、HTML和CSS

页面布局的方法

一、浮动布局(布局简单,兼容性好,可是浮动元素脱离文档流)javascript

二、绝对定位布局(布局快速,元素脱离文档流)css

三、弹性盒子布局(自应性好,兼容性差)html

四、多列布局(宽度自适应)前端

五、table布局(兼容性好)java

HTML5新特性

一、拥有更多的语义化的标签

好比:header footer nav section article aside dialoggit

二、更好的表单

input输入框有更多的输入类型:

  • color(选取颜色)
  • data(日期选择器)
  • email(e-mail 地址的输入域)
  • month(选择月份)
  • number(数值输入域)
  • range(必定范围内数字值的输入域)
  • search(用于搜索)
  • tel(定位电话号码字段)
  • time(时间)
  • url(URL输入域)

HTML5新增的表单属性

  • placehoder 输入框默认提示,在用户输入后消失。
  • required 是一个布尔值,要求输入域不能为空。
  • pattern 描述一个正则表达式用于验证input元素的值
  • min和max 设置元素最大最小值
  • step 为type为number的输入域规定合法的数字间隔
  • multiple 是一个 boolean 属性。规定上传元素中可选择多个值
  • autofocus 是一个 boolean 属性。规定在页面加载时,域自动地得到焦点。

三、视频和音频

<audio controls>
  <source src="horse.ogg" type="audio/ogg">
  <source src="horse.mp3" type="audio/mpeg">
您的浏览器不支持 audio 元素。
</audio>
复制代码
<video width="320" height="240" controls>
  <source src="movie.mp4" type="video/mp4">
  <source src="movie.ogg" type="video/ogg">
您的浏览器不支持Video标签。
</video>
复制代码

四、Canvas绘图

canvas标签订义图形,好比图表和其余图像,您必须使用脚原本绘制图形web

五、地理定位

HTML5 Geolocation API 用于得到用户的地理位置,鉴于该特性可能侵犯用户的隐私,除非用户赞成,不然用户位置信息是不可用的正则表达式

window.navigator.geolocation {
    getCurrentPosition:  fn  用于获取当前的位置数据
    watchPosition: fn  监视用户位置的改变
    clearWatch: fn  清除定位监视
}&emsp;
复制代码
navigator.geolocation.getCurrentPosition(
    function(pos){
    	console.log('用户定位数据获取成功')
    	console.log('定位时间:',pos.timestamp)
    	console.log('经度:',pos.coords.longitude)
    	console.log('纬度:',pos.coords.latitude)
    	console.log('海拔:',pos.coords.altitude)
    	console.log('速度:',pos.coords.speed)
    
    },    //定位成功的回调
    function(err){ 
    	console.log('用户定位数据获取失败')
    }        //定位失败的回调
)
复制代码

六、拖放API

拖放是一种常见的特性,即抓取对象之后拖到另外一个位置,在 HTML5 中,拖放是标准的一部分,任何元素都可以拖放算法

七、web Storage

使用HTML5能够在本地存储用户的浏览数据。早些时候,本地存储使用的是cookies。可是Web 存储须要更加的安全与快速. 这些数据不会被保存在服务器上,可是这些数据只用于用户请求网站数据上.它也能够存储大量的数据,而不影响网站的性能。数据以 键/值 对存在, web网页的数据只容许该网页访问使用。数据库

客户端存储数据的两个对象为:

localStorage - 没有时间限制的数据存储 sessionStorage - 针对一个 session 的数据存储, 当用户关闭浏览器窗口后,数据会被删除。

无论是 localStorage,仍是 sessionStorage,可以使用的API都相同,经常使用的有以下几个(以localStorage为例):

  • 保存数据:localStorage.setItem(key,value);

  • 读取数据:localStorage.getItem(key);

  • 删除单个数据:localStorage.removeItem(key);

  • 删除全部数据:localStorage.clear();

  • 获得某个索引的key:localStorage.key(index);

八、webSocket

WebSocket 是 HTML5 开始提供的一种在单个 TCP 链接上进行全双工通信的协议。

WebSocket 使得客户端和服务器之间的数据交换变得更加简单,容许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只须要完成一次握手,二者之间就直接能够建立持久性的链接,并进行双向数据传输。

在 WebSocket API 中,浏览器和服务器只须要作一个握手的动做,而后,浏览器和服务器之间就造成了一条快速通道。二者之间就直接能够数据互相传送

九、Web Worker

当在 HTML 页面中执行脚本时,页面的状态是不可响应的,直到脚本已完成。 web worker 是运行在后台的 JavaScript,独立于其余脚本,不会影响页面的性能。您能够继续作任何愿意作的事情:点击、选取内容等等,而此时 web worker 在后台运行

  • dragstart:事件主体是被拖放元素,在开始拖放被拖放元素时触发,。

  • darg:事件主体是被拖放元素,在正在拖放被拖放元素时触发。

  • dragenter:事件主体是目标元素,在被拖放元素进入某元素时触发。

  • dragover:事件主体是目标元素,在被拖放在某元素内移动时触发。

  • dragleave:事件主体是目标元素,在被拖放元素移出目标元素是触发。

  • drop:事件主体是目标元素,在目标元素彻底接受被拖放元素时触发。

  • dragend:事件主体是被拖放元素,在整个拖放操做结束时触发

css盒模型

css盒子的四个组成区域相对应,每一个盒子有四个边界:内容边界 Content edge、内边距边界 Padding Edge、边框边界 Border Edge、外边框边界 Margin Edge。

css盒模型分为两种两种标准:一种是标准模型,一种是IE模型

从上图中发现,标准盒模型的宽高就是内容(content)的宽高,而IE盒模型的宽高则是由内容(content)+内边距(padding)+边框(border)的宽高的总和。

2、DOM事件类

事件流

事件流描述的是从页面中接受事件的顺序,事件流分为冒泡流和捕获流

###事件冒泡

IE事件流叫作事件冒泡,就是事件开始是由最具体的元素(目标元素)接收,而后逐级向上传播到较为不具体的节点(文档),如图所示

事件捕获

事件捕获是从Document接收到事件,而后逐级向下传播到目标元素,如图所示

事件对象event

在触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含着全部与事件有关的信息,好比事件在其中发生的元素、键盘按键的状态、鼠标的位置、鼠标按钮的状态。

下图是事件对象经常使用的属性方法

事件委托

事件委托是利用事件冒泡,只指定一个事件处理程序来管理某一类型的全部事件。

优势:减小事件注册,节省内存、简化了dom节点更新时,相应事件的更新。 缺点:事件委托基于冒泡,对于不冒泡的事件不支持

3、HTTP协议类

http与https

http:超文本传输协议,用于从WWW服务器传输超文本到本地浏览器的传输协议。 https:是以安全为目标的HTTP通道,即HTTP下加入SSL层,HTTPS的安全基础是SSL。

区别

  • http传输的数据是明文的,https传输的数据是通过SSL加密的
  • https协议须要ca证书,费用较高。
  • 使用的连接方式,端口也不一样,通常http的端口是80,https的端口是443

https的工做原理

客户端在使用HTTPS方式与Web服务器通讯时有如下几个步骤:

  • 一、客户使用https url访问服务器,则要求web服务器创建ssl连接
  • 二、web服务器接收到客户端的请求以后,会将网站的证书(证书数中包含了公钥),传给客户端。
  • 三、客户端和web服务器开始协商ssl连接的安全等级
  • 四、客户端浏览器经过双方协商一致的安全等级,创建会话密钥,而后经过网站的公钥来加密会话密钥,并传送给网站。
  • 五、web服务器经过本身的私钥解密出会话密钥
  • 六、web服务器经过会话密钥加密与客户端之间的通讯。

http报文的组成部分

http报文由请求报文和响应报文组成

http请求方式

  • 一、GET (获取资源)
  • 二、POST (传输资源)
  • 三、PUT (更新资源)
  • 四、DELETE (删除资源)
  • 五、HEAD (得到报文首部)

GET与POST的区别

  • GET在浏览器回退是无害的,而POST会再次提交请求
  • GET请求会被浏览器主动缓存,而POST不会,除非手动设置
  • GET请求在URL中传送的参数是有长度限制的,而POST没有限制
  • GET参数经过URL传递的,POST放在Request body中
  • GET请求参数会被完整的保留在浏览器历史记录中,而POST中的参数不会被保留
  • GET请求只能进行url编码,而POST支持多种编码方式
  • GET比POST更不安全,由于参数直接暴露在URL上,因此不能用来传递敏感信息
  • 对参数的数据类型,GET只接受ASCII字符,而POST没有限制

http状态码

  • 1xx: 指示信息-表示请求已接收,继续处理
  • 2xx:成功-表示请求已被成功接收
  • 3xx:重定向-要完成请求必须进行更进一步的操做
  • 4xx:客户端错误-请求有语法错误或请求没法实现
  • 5xx:服务端错误-服务器未能实现合法的请求

http常见的状态码

  • 200 OK:客户端请求成功
  • 206 Partial Content: 客户发送一个带有Range(范围)头的GET请求,服务器完成了它
  • 301 Moved Permanently:全部页面已经转移到新的url
  • 302 Found:所请求的页面已经临时转移至新的url
  • 304 Not Modified:客户端有缓存的文档并发出一个条件性的请求,服务器告诉客户,原来缓冲的文档还能够继续使用
  • 403 Forbidden:对请求页面的访问被禁止
  • 404 Not Found:请求资源不存在
  • 500 Internal Server Error:服务器发生不可预期的错误原来缓冲的文档还能够继续使用
  • 503 Server Unavailable:请求未完成,服务器宕机

4、javascript篇

原型链

一、建立对象的方法

//第一种方式:字面量
    var o1 = {name: 'o1'};
    var o2 = new Object({name: 'o2'});
    
    //第二种方式:经过构造函数
    var M = function (name) {
        this.name = name;
    };
    var o3 = new M('o3');
    
    //第三种方式:Object.create
    var p = {name: 'p'};
    var o4 = Object.create(p);
    
复制代码

二、原型对象

每一个函数被建立的时候都会有一个prototye属性,这个属性会指向函数的原型对象。默认状况下每一个原型对象又都会获取一个constructor属性,这个属性包含一个指向prototype属性所在函数的指针(指向构造函数)

//建立构造函数
    function Person (name) {
        this.name = name;
    }
    //在Person函数的原型对象上增长一个方法
    Person.prototype.sayName = function (){
        console.log(this.name)
    }
    //Person的原型对象中的constructor属性指向Person函数
    Person.prototype.constructor===Person  //true
    //建立child实例
    var child = new Person ('xiaoming');
    child.sayName()   //xiaoming
    
复制代码

三、原型链

function Foo1(){
   this.name1 = '1';
}
function Foo2(){
   this.name2 = '2';
}
Foo2.prototype = new Foo1();
function Foo3(){
   this.name3 = '3';
}
Foo3.prototype = new Foo2();
var foo3 = new Foo3();
console.dir(foo3)

console.dir(foo3.name1);  //1
3个函数经过__proto__连接起来造成原型链,继承就是经过这个原理来的
复制代码

四、instance of VS constructor

  • instanceof 原理:检查左边对象与右边对象是否在同一条原型链上。

  • constructor原理:取对象的proto属性指向的prototype对象上的constructor字段。

五、new运算符的原理

  • 建立一个空对象,它的__proto__等于构造函数的原型对象(能够用Object.create()完成)
  • 构造函数以第1步建立的对象作为上下文,是否会返回一个对象
  • 若第2步返回了对象,则使用该对象做为新实例,不然用第1步建立的对象做为新实例
var myNew = function (func) {
    var o = Object.create(func.prototype)
    var i = func.call(o)
    return typeof i === 'object' ? i : o
}
复制代码

六、继承

js要实现继承,咱们须要一个父类,代码以下:

// 定义一个动物类
function Animal (name) {
    // 属性
    this.name = name || 'Animal';
    // 实例方法
    this.sleep = function(){
        console.log(this.name + '正在睡觉!');
    }
}
// 原型方法
Animal.prototype.eat = function(food) {
    console.log(this.name + '正在吃:' + food);
};
复制代码

一、原型链继承

核心:将父类的实例做为子类的原型

function Cat(){ 
}
Cat.prototype = new Animal();
Cat.prototype.name = 'cat';

//&emsp;Test Code
var cat = new Cat();
console.log(cat.name);  //cat
console.log(cat.eat('fish')); //cat正在吃:fish
console.log(cat.sleep());   //cat正在睡觉!
console.log(cat instanceof Animal);  //true 
console.log(cat instanceof Cat);    //true
复制代码

特色:

  • 父类原型上的属性方法,子类都能访问到
  • 实现简单

缺点:

  • 一、来自原型对象的全部属性被全部实例共享
  • 二、建立子类实例时,没法向父类构造函数传参

二、构造函数继承

核心:就是子类构造函数内部调用父类构造函数(使用call或者apply方法)

function Cat(name){
  Animal.call(this);
  this.name = name || 'Tom';
}

// Test Code
var cat = new Cat();
console.log(cat.name);  //Tom
console.log(cat.sleep());  //Tom正在睡觉
console.log(cat instanceof Animal); // false
console.log(cat instanceof Cat); // true
复制代码

特色:

  • 一、建立子类实例时,能够向父类传递参数
  • 二、能够实现多继承(call多个父类对象)

缺点:

  • 一、只能继承父类的属性方法,不能继承原型对象的属性方法
  • 二、每一个子类都有父类函数的属性方法,影响性能

三、组合继承

核心:经过原型链实现对原型属性和方法的继承,经过构造函数来实现对实例属性的继承。

function Cat(name){
  Animal.call(this); //第一次调用父类
  this.name = name || 'Tom';
}
Cat.prototype = new Animal();  //第二次调用父类
//改变构造函数的指向
Cat.prototype.constructor = Cat;

// Test Code
var cat = new Cat();
console.log(cat.name); //Tom
console.log(cat.sleep());//Tom正在睡觉!
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); // true
复制代码

特色:

  • 一、避免了原型链和构造函数的缺陷,融合了二者的优势

缺点:

  • 一、调用了两次父类构造函数

四、寄生组合式继承

核心:经过寄生方式,砍掉父类的实例属性

function Cat(name){
  Animal.call(this);
  this.name = name || 'Tom';
}
(function(){
  // 建立一个没有实例方法的类
  var Super = function(){};
  Super.prototype = Animal.prototype;
  //将实例做为子类的原型
  Cat.prototype = new Super();
})();

// Test Code
var cat = new Cat();
console.log(cat.name);  //Tom
console.log(cat.sleep()); //Tom正在睡觉!
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); //true
复制代码

特色:

  • 解决组合继承调用两次父类的缺陷

七、封装

blog.csdn.net/CCwm0129/ar…

闭包

闭包就是可以读取其余函数内部变量的函数,或者子函数在外调用,子函数所在的父函数的做用域不会被释放

this的指向

JS中的this不是指向定义他的位置,而是在哪调用它它就指向哪里,箭头函数中的 this 是依赖于所在函数的上下文的,相似于继承的关系。

5、通讯类

什么是同源策略?

同源策略限制从一个源加载的文档或脚步如何与来自另外一个源的资源进行交互(协议、域名、端口这3个构成一个源)。这是一个用于隔离潜在恶意文件的关键的安全机制

限制的内容

  • Cookie、LocalStorage和IndexDB没法读取
  • DOM没法获取
  • AJAX请求不能发送

跨域通讯的几种方式

  • JSONP
  • Hash
  • postMessage
  • WebSocket
  • CORS

一、JSONP

原理:利用script标签的异步加载来实现的,script标签src属性中的连接能够访问跨域的js脚本,利用这个特性,服务端再也不返回JSON格式的数据,而是返回一段调用某个函数的js代码,在src中进行了调用,这样实现了跨域。

举个例子:

function test(data){
    //打印后端传过来的数据
    console.log(data) //data为{a:1,b:2}
}
var url="http://www.x.com/test?callback=test"//向x.com/test告诉他要调用的函数名是“test”
//后台拦截到callback,知道要生成一个调用方法,方法名是test,并传递参数,后台处理生成以下(数据虚构)
test({a:1,b:2})
//而后前端经过script标签去访问并执行,上面的东西
var script = document.createElement('script');
    script.setAttribute('src', url);
// 把script标签加入head,此时调用开始
document.getElementsByTagName('head')[0].appendChild(script); 
//而后就会调用页面的test方法,这就是jsonp的实现原理。
复制代码

把js封装成一个通用组件

function myjsonp(URL,callback,callbackname){
	//给系统中建立一个全局变量,叫作callbackname,指向callback函数
	//定义
	window[callbackname] = callback;
	//建立一个script节点
	var oscript = document.createElement("script");
	//和image不同,设置src并不会发出HTTP请求 
	oscript.src = URL;
	oscript.type = "text/javascript";
	//script标签的请求是在上树的时候发出,请求的是一个函数的执行语句
	document.head.appendChild(oscript);
	//为了避免污染页面,瞬间把script拿掉
	document.head.removeChild(oscript);
}


//使用
myjsonp("http://sclub.jd.com/productpage/p-1217508-s-0-t-3-p-1.html?callback=abcdefg",function(data){
	console.log(data);
},"abcdefg");

复制代码

二、hash

原理:原理是利用location.hash来进行传值。

//利用hash,场景是当前页面A经过iframe或frame嵌入了跨域的页面B
//在A中的伪代码以下:
var B = document.getElementsByTagName('iframe');
B.src = B.src + '#' + 'data';

//在B中的伪代码以下:
//onhashchange事件是用来监听当前页面的hash有没有改变
window.onhashchange = function () {
    var data = window.location.hash;
}
复制代码

三、postMessage

举例来讲,父窗口http://a.com向子窗口http://b.com发消息,调用postMessage方法就能够了

a页面

<iframe id="frame1" src="http://127.0.0.1/JSONP/b.html" frameborder="1"></iframe>
document.getElementById('frame1').onload = function(){
    //contentWindow返回的是iframe的window对象,因此后面能够接着调用document方法
    var win = document.getElementById('frame1').contentWindow;
    win.postMessage("我是来自a页面的","http://127.0.0.1/JSONP/b.html")
}
复制代码

b页面

window.onmessage = function(e){
    e = e || event;
    console.log(e.data);//我是来自a页面的数据
    console.log(e.source);//发送消息的窗口对象
    console.log(e.origin);//发送消息窗口的源
}
复制代码

四、WebSocket

WebSocket protocol是HTML5一种新的协议。它实现了浏览器与服务器全双工通讯,同时容许跨域通信,是server push技术的一种很好的实现

五、CORS

整个CORS通讯过程,都是浏览器自动完成,不须要用户参与。对于开发者来讲,CORS通讯与同源的AJAX通讯没有差异,代码彻底同样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感受。

所以,实现CORS通讯的关键是服务器。只要服务器实现了CORS接口,就能够跨源通讯。

参考资料:www.ruanyifeng.com/blog/2016/0…

6、安全类

CSRF

一、基本概念

CSRF,即(Cross-site request forgery), 中文名为跨站请求伪造。是一种挟持用户在当前已登陆的Web应用程序上执行非本意的操做的一种攻击方式。

二、攻击原理

举个例子:当用户经过身份认证登陆了网站A,这时候网站A的cookie会保存在浏览器中,而后用户又访问了网站B,这时候网站B会有一个引诱点击,这个引诱点击每每是个连接,这个连接指向的就是网站A的API接口,由于浏览器会自动上传cookie,当网站A对身份从新确认发现是合法用户,因此就执行这个接口的动做。

综上所诉:要完成一个CSFR攻击,受害者必须依次完成两个步骤

  • 一、登陆受信任的网站A,并在本地生成Cookie
  • 二、在不登出A的状况下,访问了危险网站B

三、防护措施

Token验证:CSRF原理中访问漏洞接口的时候浏览器只上传了cookie,没有手动的上传一个token。这个token是用户登陆注册甚至只是访问网站A,服务器会自动向用户本地存储一个token,在用户访问各个接口的时候,若是没带这个token,服务器就不会经过验证。因此当用户点击引诱连接,这个连接只会自动携带cookie,可是不会自动携带token

Referer验证 (Referer指的是页面来源):服务器经过判断页面来源是否是本身站点的页面来源,若是是就执行接口动做,若是不是一概拦截。

XSS

一、基本概念

XSS就是跨域脚本攻击

二、攻击原理

反射型:发出请求时,XSS代码出如今URL中,做为输入提交到服务器端,服务器端解析后响应,XSS代码随响应代码一块儿传给浏览器,最后浏览器解析执行XSS代码。整个过程像一次反射,故叫反射型XSS

储存型:也叫持久型XSS,主要是将XSS代码发送到服务器(无论是数据库、内存仍是文件系统等。),而后在下次请求页面的时候就不用带上XSS代码了

三、防范措施

  • 对重要的cookie设置httpOnly, 防止客户端经过document.cookie读取cookie。服务端能够设置此字段
  • 是服务端要进行过滤

7、算法篇

  • 排序(快速排序、冒泡排序、选择排序)
  • 递归

排序

###一、快速排序

原理:

  • 在数据集之中,选择一个元素做为“基准”。
  • 全部小于“基准”的元素,都移到“基准”的左边,全部大于“基准”的元素,都移到“基准”的右边。
  • 对“基准”左边和右边的两个子集,不断重复第一步和第二步,直到全部子集只剩下一个元素为止。
var quickSort = function(arr) {
    
        //若是数组长度小于等于1无需判断直接返回便可
        if (arr.length <= 1){ return arr; }
        
        var pivotIndex = Math.floor(arr.length / 2);
        
        //取基准点的值,splice(index,1)函数能够返回数组中被删除的那个数
        var pivot = arr.splice(pivotIndex, 1)[0];
        console.log(pivot)
        var left = [];
        var right = [];
        
        for(var i = 0; i < arr.length; i++){
            if (arr[i] < pivot){
                left.push(arr[i]);
            } else {
                right.push(arr[i]);
            }
        }
        
        //递归执行以上操做,对左右两个数组进行操做,直到数组长度为<=1; 
        return quickSort(left).concat([pivot], quickSort(right));
    }
复制代码

二、冒泡排序

原理:

  • 1.比较相邻的两个元素,若是前一个比后一个大,则交换位置。

  • 2.第一轮的时候最后一个元素应该是最大的一个。

  • 3.按照步骤一的方法进行相邻两个元素的比较,这个时候因为最后一个元素已是最大的了,因此最后一个元素不用比较

function bSort(arr) {
  var len = arr.length;
  for (var i = 0; i < len-1; i++) {
    for (var j = 0; j < len - 1 - i; j++) {
         // 相邻元素两两对比,元素交换,大的元素交换到后面
        if (arr[j] > arr[j + 1]) {
            var temp = arr[j];
            arr[j] = arr[j+1];
            arr[j+1] = temp;
        }
    }
  }
  return arr;
}

//举个数组
myArr = [20,18,27,19,35];
//使用函数
bSort(myArr)//[18,19,20,27,35]
复制代码

三、选择排序

原理:

  • 把每个数都与第一个数比较,若是小于第一个数,就把它们交换位置;这样一轮下来,最小的数就排到了最前面;重复n-1轮,就实现了选择排序
function selectSort (arr) {
        var len = arr.length;
        var temp;
        for(var i=0; i<len-1; i++){
            for(var j=i+1; j<len; j++){
                if(arr[i]>arr[j]){
                    //互换位置
                    temp = arr[j];
                    arr[j] = arr[i];
                    arr[i] = temp;
                }
            }
        }
        return arr;
    }
    
    var oldArr = [3,9,4,5,2,8];
    selectSort(oldArr); //[2, 3, 4, 5, 8, 9]
复制代码

递归

www.cnblogs.com/huangshikun…

8、渲染机制

blog.csdn.net/buzhibujuel…

9、js运行机制

js的单线程机制

概念:简单地说就是同一时间只能作一件事,当有多个任务时,只能按照一个顺序一个完成了再执行下一个

任务队列

任务队列能够分红两种,一种是同步任务(synchronous),另外一种是异步任务(asynchronous)。同步任务指的是,在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;异步任务指的是,不进入主线程、而进入"任务队列"(task queue)的任务,只有"任务队列"通知主线程,某个异步任务能够执行了,该任务才会进入主线程执行。

  • 一、全部同步任务都在主线程上执行,造成一个执行栈(execution context stack)
  • 二、主线程以外,还存在一个"任务队列",只要异步任务有了运行结果,就在"任务队列"之中放置一个事件
  • 三、一旦"执行栈"中的全部同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,因而结束等待状态,进入执行栈,开始执行
  • 四、主线程不断重复上面的第三步

举个例子:

console.log(1)  //这个是同步任务,放入主线程里
    
setTimeout(function(){ //这个是异步任务,放入任务队列中,等同步任务执行完毕,才能执行
    console.log(2)
},0)

console.log(3) //这个是同步任务,在主线程里

//运行结果是132
复制代码

Event Loop

主线程从任务队列中读取事件,这个过程是循环不断的,因此整个的这种运行机制又称为Event Loop(事件循环)

异步任务的执行顺序准确的划分方式是:

  • 宏任务(macro-task):包括总体代码script,setTimeout,setInterval
  • 微任务(micro-task):Promise,process.nextTick

举个例子:

setTimeout(function(){
     console.log('定时器开始啦')
 });
 
 new Promise(function(resolve){
     console.log('立刻执行for循环啦');
     for(var i = 0; i < 10000; i++){
         i == 99 && resolve();
     }
 }).then(function(){
     console.log('执行then函数啦')
 });
 
 console.log('代码执行结束');
 
 //执行结果是:立刻执行for循环啦 > 代码执行结束 > 执行then函数啦 > 定时器开始啦
 
 //执行原理是:
首先执行script下的宏任务,遇到setTimeout,将其放到宏任务的【队列】里

遇到 new Promise直接执行,打印"立刻执行for循环啦"(Promise函数体里面是同步任务)

遇到then方法,是微任务,将其放到微任务的【队列里】

打印 "代码执行结束"

本轮宏任务执行完毕,查看本轮的微任务,发现有一个then方法里的函数, 打印"执行then函数啦"

到此,本轮的event loop 所有完成。


下一轮的循环里,先执行一个宏任务,发现宏任务的【队列】里有一个 setTimeout里的函数,执行打印"定时器开始啦"
复制代码

10、页面性能

提高页面性能的方法有哪些?

  • 资源压缩合并,减小HTTP请求
  • 非核心代码异步加载
  • 利用浏览器缓存
  • 使用CDN
  • 预解析DNS

非核心代码异步加载

一、异步加载的方式

  • 动态脚本加载
  • script标签使用defer属性
  • script标签使用async属性

二、异步加载的区别

  • defer是在HTML解析以后才会执行,若是多个,按照加载的顺序依次执行
  • async是在加载以后当即执行,若是多个,执行顺序和加载顺序无关

浏览器缓存

浏览器缓存:“分为强制缓存和协商缓存”,当客户端向浏览器发送请求的时候,若是没有缓存则直接请求服务器。若是有则根据缓存状态来是否从缓存中获取对应的文件

做用:

  • 减小冗余的数据传输
  • 减小服务器负担
  • 加快客户端加载网页的速度

一、强制缓存

利用Expires和Cache-Control两个字段来控制

expires:是缓存过时时间(即资源过时时间),是个绝对值。因此若是客户端更改时间,会致使缓存混乱。因此http:1.1增长了cache-control:max-age 字段,它是一个相对的时间

Cache-Control与Expires能够在服务端配置同时启用,同时启用的时候Cache-Control优先级高。

Control:max-age=3600,表明着资源的有效期是3600秒

二、协商缓存

协商缓存涉及到两组header 字段。

Etag和If-None-Match

Last-Modified和If-Modified-Since
复制代码

Etag和If-None-Match

他们返回的是一个校验码,是个hash值。Etag可以保证资源都是惟一的,是客户端请求服务器的时候服务器返回的。若是资源变化了Etag也会发生变化。当再次请求服务器的时候服务器根据浏览器上送的If-None-Match(以前服务器返回的etag值)值来判断是否命中缓存。

Last-Modified和If-Modified-Since

  • 浏览器第一次请求一个资源的时候,服务器返回的header中会加上Last-Modify,Last-modify是一个时间标识该资源的最后修改时间,例如Last-Modify: Thu,31 Dec 2037 23:59:59 GMT。

  • 当浏览器再次请求该资源时,request的请求头中会包含If-Modify-Since,该值为缓存以前返回的Last-Modify。服务器收到If-Modify-Since后,根据资源的最后修改时间判断是否命中缓存。

  • 若是命中缓存,则返回304,而且不会返回资源内容,而且不会返回Last-Modify。

  • Last-Modified与ETag是能够一块儿使用的,服务器会优先验证ETag,一致的状况下,才会继续比对Last-Modified,最后才决定是否返回304。

相关文章
相关标签/搜索