考点分析
页面布局、css盒模型、DOM事件、HTTP协议、面向对象、原型链
通信:异步通信、前后端通信
安全:CSRF XSS
算法:不规律
一、页面布局
回答:有5种布局解决方案
1、浮动 2、定位 3、flexbox布局 4、table表格布局 5、grid布局
延伸:
1、每个解决方案的优缺点,他们之间的比较
回答:
浮动问题:缺点:需要清楚浮动,脱离文档流,处理不好会出现问题。优点:兼容性好
绝对定位:缺点:同样脱离文档流,下面子元素也脱离文档流,可使用性比较差。 优点:快捷。
flexbox布局:缺点:IE8不支持 优点:比较完美解决方案
表格布局:缺点:除了大家诟病的那些缺点(繁琐、不利于seo),还有同行一列单元格增高,同时增高问题。优点: 兼容性好 具体情况比较看 用flexbox还是用表格布局。
grid布局(网格布局):缺点:优点:
2、假如把高度去掉,哪个方案不太适用了?
回答:只有flex布局和表格布局获胜
3、兼容性,真正的在业务中哪个是最实用的?
二、CSS盒模型
1、谈谈你对CSS盒模型的认识
回答:
css盒模型是css的基石
CSS盒模型本质上是一个盒子,包括margin-border-padding-content
基本概念:标准模型+IE模型
2、标准模型和IE模型的区别?
回答:
标准模型的宽和高只是content的宽和高
IE模型的宽和高还包括 border和padding
3、css如何设置这两种模型?
回答:
box-sizing:content 浏览器默认的是标准模型
box-sizing:border-box
4、js如何设置获取盒模型对应的宽和高?
dom.style.width/height 只能取出内联样式的宽和高
dom.currentStyle.width/height 取出的是渲染后的宽和高,但是只有IE支持
window.getComputedStyle(dom).width/height 兼容
dom.getBoundingClientRect().widht/height 获取元素绝对位置,left,top,widht,height
5、实例题(根据盒模型解释边距重叠),父元素的高是多少?
回答:默认是100,父元素加上“overflow:hidden”属性后,高度变成110;
边距重叠的三种情况:a、父子元素,子元素margin-top设值 b、兄弟元素,设margin值,原则上取最大值 c、空元素margin值也会取最大值
6、BFC(边距重叠解决方案)
回答:
BFC基本概念:块级元素格式化上下文 block formatting context (BFC比IFC常问)
—> BFC的原理(就是渲染规则:1,BFC元素的垂直方向会发生重叠;2,BFC的区域不会与
浮动元素的box重叠;3,BFC在页面上是一个独立的容器,外面的元素和里面的元素不会相互影
响;4, 计算BFC高度时,浮动元素也会参与计算)
—> 如何创建BFC(1,float值不为none,只要设置了浮动,就创建了BFC;position值
不为static和relative就创建了BFC;3,display属性inline-block, table-cell, table等等都可以;4,
overflow: hidden/auto(不为visible即可))
—> BFC的使用场景
编程演示:
a 给元素创建一个父元素,创建一个BFC,就可以解决垂直方向边距重叠。
b 元素侵占浮动元素的剩余空间,则在这个元素上面创建BFC,就可以解决,使得BFC不与float
重叠。
c 父级元素创建BFC,可以解决由于浮动元素导致父级元素高度为0的情况。创建方法可以是:
父级也float,或者父级overflow:hidden/auto
三、DOM事件
1、基本概念:DOM事件级别
回答:DOM标准定义的级别:DOM0、DOM2、DOM3
DOM0, element.onclick = function(){}
DOM2, element.addEventListener(’click’, ()=>{}, false)
DOM3, element.addEventListener(‘keyup’, ()=>{}, false)
2、DOM事件模型
回答: 捕获和冒泡
3、事件流
回答:一个完整的事件流分三个阶段:捕获阶段、目标阶段、冒泡阶段
4、描述DOM事件捕获的具体流程
回答:window --> document —>html —> body —> …… —> target
如何获取html标签?
document.body ==> 获取body
document.documentElement ==> 获取html
5、Event对象的常见应用
回答:
event.preventDefault() // 阻止默认事件行为
event.stopPropagation() // 阻止冒泡事件行为
event.stopImmediatePropagation() // (一个按钮注册两个事件a、b)在a的响应函数中加此语句,可以阻止b事件
event.currentTarget // 和this 的作用是差不多的,始终返回的是绑定事件的元素
event.target // 当前被点击的元素
(for循环遍历节点添加事件的时候都可以用事件委托来做,可以提高性能。)
6、自定义事件
// 创建自定义事件
var eve = new Event(‘custome’);
ev.addEventListener(‘custome’, ()=>{})
// 触发自定义事件
ev.dispatch(eve)
window.addEventListener('click',function(){},false) 默认是fasle,表示冒泡阶段触发
也可以使用CustomEvent创建自定义事件,并且可以指定一些参数
四、类型转换
1、数据类型
回答:最新ECMAScript标准定义了7种数据类型
原始类型:Boolean Number String Symbol Null Undefind
对象:Object
2、显式类型转换
回答:显式调用Number函数、String函数、Boolean函数
Number函数
原始类型转换
数值:转换后还是原来的值
字符串:如果可以被解析为数值,则转换为相应的数值,否则得到NaN。空字符串转为0
布尔值:true转为1,false转为0
undefined:转为NaN
null:转为0
对象类型转换
先调用对象自身的 valueOf 方法,如果返回原始类型的值(数值、字符串、布尔),则直接使用Number方法,结束。
如果返回复合类型的值,则调用 toString方法,如果返回原始类型的值,则使用Number方法,结束。
如果返回复合类型的值,则报错。
String函数
原始类型转换:
数值:转为相应的字符串
字符串:转换后还是原来的值
布尔值:true 转为"true" ,fasle 转为"false"
undefined:"undefined"
null:转为"null"
对象类型转换:
先调toString方法,如果返回原始类型,则使用String方法,结束。
如果返回复合类型,再调用valueOf,如果返回原始类型,则使用String方法,结束。
如果返回复合类型,则报错。
Boolean函数
原始类型转换:
undefined、null、+0、-0、NaN、''(空字符串) 他们都返回false 6个
其他的都是true
3、隐式类型转换
回答:
四则运算(+-×)
判断语句(if、三目运算符)
Native调用(console.log() alert() 自动转换为字符串类型)
五、HTTP协议类
1、HTTP协议的主要特点
回答:简单快速、灵活、无连接、无状态(后两个一定要说)
简单快速:每个资源都是固定的,统一资源符
灵活:通过一个http协议就可以完成不同数据类型的传输,只需要更改头文件中的数据类型
无连接:连接一次就断掉,不会保持连接
无状态:一次连接之后,服务端是无法记住客户端的状态的(通过session等手段才能实现)
2、HTTP报文的组成部分
回答:HTTP报文由请求报文和响应报文组成;请求报文包括:请求行、请求头、空行、请求体; 响应报文包括:状态行、响应头、空行、响应体
请求行包含(http方法、页面地址、http协议以及版本)(example: GET /home/xxx HTTP/1.1)
请求头:(key-value值)告诉服务端请求的内容是什么
空行(告诉服务器端该解析请求体了)
------------------------
状态行:(example:HTTP/1.1 200 OK)
3、HTTP方法
回答:
GET —> 获取资源
POST —> 传输资源
PUT —> 更新资源
DELETE —> 删除资源
HEAD —> 获取报文首部
4、GET和POST的区别
回答:(记住三四个即可)
GET在浏览器中回退是无害的,而POST会再次提交请求
GET产生的URL地址可以被收藏,而POST不可以
GET请求可以被浏览器主动缓存,POST不会,需要手动设置
GET请求只能进行url编码,而POST支持多种编码方式
GET请求的参数会被完整的保留在浏览器历史记录里,而POST中的参数不会被保留
GET请求在URL中传输的参数长度是有限制的,而POST请求没有限制
对参数的数据类型,GET只接受ASCII字符,而POST没有限制
GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息
GET参数通过URL传递,POST放在Request body中
5、HTTP状态码
回答:
1xx:指示信息 ---请求已接收,继续处理
2xx:成功 ---表示请求已被成功接收
3xx:重定向 --- 要完成请求必须进行更进一步的操作
4xx:客户端错误 --- 请求有语法错误或请求无法实现
5xx:服务端错误 --- 服务器未能实现合法的请求
200,206,301,302,304,400,401,403,404,500,503
6、什么是持久连接
回答:
HTTP协议采用“请求-应答”模式,当使用普通模式,即非keep-alive模式时,每次连接都需要重新
建立。持久连接只有在1.1版本才支持。
7、什么是管线化
回答:
持久连接的情况下,请求和连接是对应的,即:
请求1-->响应1-->请求2-->响应2
管线化是指,将请求和响应都进行了打包进行发送:
请求1,2,3—>响应1,2,3
管线化机制是通过持久连接完成的,至少1.1版本
只有GET和HEAD请求可以进行管线化,POST有所限制
初次建立不应启动管线化,因为服务端不一定支持1.1
管线化不会影响到来的顺序
HTTP/1.1要求服务器支持管线化,但并不要求服务端一定能进行管线化处理,只是要求对于管线化的请求不失败即可
开启管线化很可能不会带来大幅度的性能提升,而且很多服务器端和代理程序对管线化的支持
并不好,因此现代浏览器,如Chrome和Firefox是默认关闭管线化的。
六、原型链
1、创建对象有几种方法
回答:
对象字面量:
var 01 = {name: ‘o1’};
var 011 = new Object({name: ‘o11’});
构造函数:
var M = function(){
this.name = ‘m’;
}
var o2 = new M();
Object.create():
var P = {name: ‘o3'}
var o3 = Object.create(P);
2、原型,构造函数,对象实例,原型链
构造函数—new—>实例对象—__proto__—>原型对象
构造函数—prototype—>原型对象
构造函数<—constructor--原型对象
+作用域链是什么?(scope chain)
当代码在一个环境执行时,会创建由变量对象构成的一个作用域链。
如果这个环境是函数,则将其活动对象(activation object)作为变量对象。
函数被创建的时候,会创建一个包含全局变量对象的作用域链,保存在内部属性[Scope]中。
当调用函数时,会创建一个执行环境,然后复制函数的[Scope]属性中的对象构建起执行环境的作用域链。然后呢又有一个活动对象(使用this、arguments、其他命名参数的值初始化)(在此作为变量对象)被创建并被推入作用域链的前端。
作用域链的本质是一个指向变量对象的指针列表,它只引用并不实际包含对象。
作用域链的用途:保证对执行环境有权访问的变量和函数的有序访问。
3、 instanceof的原理
回答:判断实例对象__proto__属性和构造函数的prototype是不是同一个引用 ,在判断实例对象是不是这个构造函数的实例的时候,其实判断的是实例的__proto__属性与构造函数的prototype是不是引用的同一个地址。 实例的原型对象有可能是另一个类型的实例,以此类推。在intanceof判断,实例对象是不是构造函数(原型对象指向的超类型的原型对象的构造函数)的实例时候,返回true
4、new运算符
Step1: 一个新对象被创建,它继承自foo.prototype
==>
Step2: 构造函数foo被执行,执行的时候,相应的传参会被传入,同时上下文(this)会被指定为
这个新实例。new foo等同于new foo(),只能用在不传递任何参数的情况下
==>
Step3: (如果构造函数返回了一个“对象”,那么这个对象会取代整个new出来的结果。如果构造函
数没有返回对象,)那么new出来的结果为步骤1创建的对象。
new的代码:
var new2 = function(func) {
var o = Object.create(func.prototype);
var k = func.call(o);
If(typeof k === ‘object’ ) {
return k;
} else {
return o;
}
}
var M = function (name) {this.name =name;};
o6 = new2(M) new M
----------------
How new
works
Brendan Eich wanted Javascript to look like traditional Object Oriented programming languages such as Java and C++. In those, we use the new
operator to make a new instance of a class. So he wrote a new
operator for Javascript.
- Create the instance of the class. It is an empty object with its
__proto__
property set toF.prototype
. - Initialize the instance. The function
F
is called with the arguments passed andthis
set to be the instance. - Return the instance
Now that we understand what the new operator does, we can implement it in Javascript.
1 function New (f) { 2 /*1*/ var n = { '__proto__': f.prototype }; 3 return function () { 4 /*2*/ f.apply(n, arguments); 5 /*3*/ return n; 6 }; 7 }
七、面向对象
1、类与实例:怎么生成一个类,类的声明,怎么生成一个实例
回答:
1 //类的声明 2 //*ES5中class声明*/ 3 function Person () { 4 this.name = 'name'; 5 } 6 //*ES6中class声明*/ 7 class Person2 { 8 constructor () { 9 this.name = 'name'; 10 } 11 } 12 //实例化类的对象 13 new Person(); 14 new Person2();
2、类与继承:如何实现继承,继承的几种方式
回答:
实现继承的基本原理就是原型链。
第一种,借助构造函数实现继承:
1 function Parent1 () { 2 this.name = 'parent1'; 3 } 4 function Child1 () { 5 Parent1.call(this); //这句是执行父级的构造函数,也可用apply,改变函数运行的上下文 6 this.type = 'child1'; 7 } 8 new Child1();
缺点:既然是函数里面的方法,就谈不上函数的复用性。Parent1的prototype上面的属性或者方法是不能被Chlid1继承的,只实现了部分继承。
第二种,借助原型链实现继承:
1 function Parent2 () { 2 this.name = 'parent2'; 3 this.play = [1,2,3]; 4 } 5 function Child2 () { 6 this.type = 'child2'; 7 } 8 Child2.prototype = new Parent2(); 9 new Child2(); 10 var s1 = new Child2(); 11 var s2 = new Child2(); 12 s1.play.push(4); 13 console.log(s1.play, s2.play); // [1,2,3,4] [1,2,3,4]
缺点:
父类中增加新的属性,那么所有的实例都会同时改变。如果某个实例的属性值(来自父类的)发生了
变化,那么其他实例也都跟着发生了变化。因为所有实例的__proto__是同一个,所以相互之间会有
影响。(还有一个问题,这创建子类型的实例时,不能向超类型的构造函数中传递参数。)
第三种,组合方式:
1 function Parent3() { 2 this.name = ‘parent3’; 3 This.play = [1,2,3,4]; 4 } 5 function Child3(){ 6 Parent3.call(this); 7 this.type = ‘child3’; 8 } 9 Child3.prototype = new Parent3(); 10 var s3 = new Child3(); 11 var s4 = new Child3();
缺点:父级的构造函数执行了两次,而并没有必要
优化方式1:
1 function Parent4() { 2 this.name = ‘parent4’; 3 This.play = [1,2,3,4]; 4 } 5 function Child4(){ 6 Parent4.call(this); 7 this.type = ‘child4’; 8 } 9 Child4.prototype = Parent4.prototype; 10 var s5 = new Child4(); 11 var s6 = new Child4(); 12 s5 instanceof Child4 ======>>>true 13 s5 instanceof Parent4 ======>>>true
问题:
怎么区分一个对象是由子类实例化的,还是父类实例化的(直接实例化)
constructor方法在这里会出问题,因为s5.constructor 指向的是 Parent4。(其实前面的方法也有
这个问题)
优化方式2:
1 function Parent5() { 2 this.name = ‘parent5’; 3 This.play = [1,2,3,4]; 4 } 5 function Child5(){ 6 Parent5.call(this); 7 this.type = ‘child5’; 8 } 9 Child5.prototype = Object.create(Parent5.prototype); 10 Child5.prototype.constructor = Child5; 11 var s7 = new Child5(); 12 var s8 = new Child5();
完美!(此处王祖蓝)
八、通信类
1、什么是同源策略及限制:
回答:
源:协议,域名,端口
限制:不是一个源的文档没有权利去操作另一个源的文档,包括Cookie, LocalStorage, IndexDB,
DOM无法获取, Ajax无法发送
同源策略限制不同的源的文档之间进行交互。
2、前后端如何通信:
回答:
Ajax:同源限制
WebSocket:不受限制
CORS:支持同源,也支持非同源(新的通信协议标准)
3、如何创建Ajax:有以下几个要点
XMLHttpRequest对象的工作流程
兼容性处理
事件的触发条件
事件的触发顺
4、跨域通信的几种方式
JSONP
Hash(hash改变,页面是不刷新的,?后是search,改变时会刷新页面)
postMessage(新技术,h5的标准)
WebSocket
CORS(可以理解为支持跨域通信的变种Ajax。当你在浏览器中发送一个ajax跨域请求时,浏
览器会在http头中加入一个origin。如果只是一个普通的ajax,则会被浏览器拦截)
5、JSONP的原理:
回答:利用script标签的可以不同源加载实现的。
1. 在window全局注册一个函数
2. 给服务端传递这个函数的名字,同时可以有参数
3. 服务端返回这个函数,内部填充有数据,就可以拿到数据
4. 删除全局注册的那个函数
6、Hash的原理
页面A中通过iframe或frame嵌入了B窗口。目标是A给B发消息。
1. 拿到B的url地址
2. 改变其hash值
3. 在B中接收,onhashchange
7、WebSocket的原理:
1. var ws = new WebSocket('wss:echo.websocket.org');
2. onopen, onmessage, onclose
8、CORS的原理:
fetch(‘/some/url’, {
method: ‘get’,
// 加一些配置就可以实现跨域的通信,这里可以参考一篇文章
}).then(function (response) {
// xxx
}).catch(function(err){
// yyy
});
八、安全类
1、前端安全有几种分类
XSS
CSRF
CSRF:
基本概念和缩写:跨站请求伪造,cross-site request forgery
攻击原理:
用户 ——1登陆——> 网站A
用户 <—— 2下发cookie—— 网站A
用户 —— 3访问——> 网站B
用户 <——4引诱点击—— 网站B
用户 ——5访问——> 网站A(A就会通过cookie判断,觉得是合法用户)
XSS:
跨域脚本攻击:Cross-site scripting
攻击原理:不需要登陆认证,是向页面注入脚本,写入一些标签。
防御措施:目的是让插入的这些东西无法执行
九、算法类
略
-------------二面三面--------------
一、渲染机制
二、js运行机制
三、页面性能
提高页面性能的方法有哪些?
1、资源压缩合并,减少http请求
2、非核心代码异步加载 -> 异步加载的方式 -> 异步加载的区别
3、利用浏览器缓存 -> 缓存的分类 -> 缓存的原理
4、使用CDN (CDN加速资源是非常快的,属于网络优化这一块)
5、预解析DNS
<meta http-equiv = "x-dns-prefetch-control" content = "on">
<link rel = "dns-prefetch" href="//host_name_to_prefetch.com">
6、sprite雪碧图处理
四、错误监控