Interview

235 阅读11分钟

1 页面布局

1.1 上中下:

浮动,定位,flex, table, grid

1.2 左中右:

定位,flex, table, grid


2 css盒模型:

2.1 标准模型:

包含margin border padding content,元素的宽度指的是content的宽度

2.2 IE模型:

也包含margin border padding content, 不过此时元素的宽度指的是border的宽度

2.3 如何切换:

box-sizing: border-box/content-box


3 获取元素宽高的几种方式

//第一种
dom.style.width
//第二种IE
dom.currentStyle.width
//第三种Chrome FireFox ,其中第二个参数若是为'before'或者'afte'则是代表获取before和after的属性值
//伪元素:虚拟元素,并不存在与dom树中,伪类:通过常规选择器无法获取的选择器
window.getComputedStyle(dom,null).width
//第四种 此种方法有六种属性,分别为left,right,top,bottom,width,height
dom.getBoundingClientRect().width

4 BFC

4.1 BFC是什么?有什么特点?

它是块级格式上下文 (1) 垂直方向的边距会发生重叠 (2) BFC区域的元素不与浮动元素重叠 (3) BFC是一个独立的元素,外面的元素不会影响内部元素,内部元素也不会影响外部元素 (4) 计算BFC的高度时,浮动元素的高度也会参与计算(如果子元素浮动了,通过把父级元素设置成bfc,则可以清除浮动)

4.2 触发bfc

overflow//(除了visible),
float,
positoin=absolute,
display=table 

4.3 BFC应用场景

  1. 去除边距重叠现象
  2. 清除浮动(让父元素的高度包含子浮动元素)
  3. 避免某元素被浮动元素覆盖
  4. 消除文字换套

5 Dom事件

5.1 事件级别

//Dom0 
ele.onClick
//Dom2 增加一些基本事件,例如click mouseover mouseout
ele.addEventListener('click',function(){},false);
ele.attachEvent('onClick',function
//Dom3 增加一些额外的事件,例如focus,blur,keydown,keyup
ele.addEventListener('click',function(){},false)

5.2 事件模型

捕获和冒泡

5.3 事件流

先捕获,然后到目标元素,在冒泡给window

5.4 dom捕获事件的具体流程

window document html body

5.5 事件类

e.preventDefault()
e.stopPropagation()
//下面这个主要作用就是如果要是给一个按钮注册两个事件
//若是在第一个事件处理函数中加上这个,则第二个函数不会触发
e.stopImmediatePropagation()
e.target
e.currentTarget

5.6 自定义事件

var event = new Event('custom');
ele.addEventListener('custom',function(){},false);
ele.dispatchEvent(event);

6 HTTP协议

6.1 主要特点

简单快速(统一资源定位符uri快速访问) 灵活:可以传递多种数据 无连接:连接一次就断开,不保持连接 无状态:协议对于事务的处理没有记忆能力,这就意味着如果后续处理需要前面的信息,必须重传,这样可能导致每次连接传送的数据量增大。

6.2 http报文组成

请求报文

请求行: http方法,地址,协议,版本
请求头:包含表示请求和响应的各种条件和属性的各类首部
    User-Agent:产生请求的浏览器类型。
    Accept:客户端可识别的内容类型列表。
    Host:
空行:告诉服务器接下来是请求体了
请求体:传递的数据

响应报文

状态行:包含响应结果的状态码,原因短语和HTTP版本
响应头:key和value值,包含返回日期,内容类型,服务器是apache
空行:
响应体:响应数据

6.3 http方法

get : 获取资源
post:传输资源
put: 更新资源
delete:删除资源
head: 获取报文首部

6.4 post和get区别

get请求在浏览器回退时无害,而post请求会再次发起
get请求会被浏览器主动缓存,而post不会,除非手动设置
get请求参数会被完整保存在历史记录里,而post请求则不会
get请求只接受ASCII码字符,而post请求不会
//get请求只能进行url编码,而post请求支持多种
get请求在url中传送的参数有限。
get请求通过url传递,而post请求放在请求体中

6.5 http状态码

1xx:指示信息,请求正在处理中
2xx:请求正常接收
200: ok
206:“Partial Content”响应: 客户端发送了一个带有Range请求头的Get请求,是表明自己只需要url上部分的资源,服务器完成了它。 比如:video audio播放一个很大的视频/音频地址时,一般会返回206
3xx:重定向 需要进行附加操作才算完成请求
301: 永久重定向,所请求的页面已经转移至新的URL
302: 临时重定向
304:缓存,服务器告诉浏览器可以直接使用缓存,不用请求服务器了
(当客户端发起一个有条件的get请求并且该请求已被允许,但是文档的内容自上次访问以来,并未发生变化,则服务器返回304状态码,也就是,服务端执行了get,但是文件并未变化:
客户端在请求一个文件的时候,发现缓存文件里面有lastModified, 那么在请求中会包含一个If Modified Since, 这个时间就是缓存文件的lastModified。 因此如果请求中包含 IF Modified Since, 就说明已经有缓存在客户端了,服务端只需要判断这个时间和当前
请求的文件的修改时间就可以确定是返回304还是200)
4xx(客户端错误)
400: 客户端语法错误
401: 请求授权失败
403: 请求不允许 Forbidden资源禁止被访问
404: 没有发现文件、查询或URl
5xx(服务器端错误)
500:服务器不可预计的错误
501: "Internal Server Error" 服务器端在执行请求时发生了错误,此时服务器并没有正常工作
503: 服务器当前不能处理客户端的请求 临时过载和当机
504: 服务器没连上
505: 服务器不支持或拒绝支请求头中指定的HTTP版本

6.6 持久连接

当使用connection:keep-alive模式

6.7 管线化

在持久连接的情况下,将所有请求一次性都返回
只有get和head可以进行管线化
浏览器默认是关闭的,初次连接不应该启用

7 通信类

7.1 同源策略及限制

协议,域名,端口都相同

cookie,localstorage, indexdb无法获取
dom无法获取
ajax请求无效

7.2 同源策略的好处

为了保障用户信息的安全,防止恶意的网站窃取数据;限制一个源的脚本从另外一个源加载资源的行为,在对恶意脚本的防护上起到巨大的作用。同源策略不是禁止脚本的执行,而是禁止读取HTTP的响应。也就是跨域的资源访问请求是允许的,但是服务端返回的数据是禁止读取的。

7.3 跨域的实现方式有哪几种?

jsonp hash postMessage websoket cors

7.4 前后端通讯的基本方式

ajax websoket cors

7.5 jsonp实现跨域的原理是什么?

script中url带一个参数(callback)过来,服务端获取到这个参数,就会在生成js代码时,以这个callback参数作为方法名,再把数据放到这个方法里。这样各个站点就可以调用各自的方法了。这也是jsonp的一个要点。

<script type="text/javascript" src="http://example.com/Index.aspx?callback=Hello">
</script>
function Hello(data){
 alert(data.result);
}

8 对象和原型

8.1 new运算符的执行都做了一些什么事情?

1、创建一个空对象,作为将要返回的对象实例。 2、将这个空对象的原型,指向构造函数的prototype属性。 3、将这个空对象赋值给函数内部的this关键字。 4、开始执行构造函数内部的代码。 5、最后将this返回

8.2 创建对象有几种方式?

  • 第一种

var obj1 = {name: 'bill'};

var obj2 = new Object({name: 'bill'})

  • 第二种

(```)

var M = function(name) {
    this.name: name;
}
var obj3 = new M();

(```)

  • 第三种

    var p = {name: 'bill'}

    var obj4 = Object.create(p)

8.3 原型对象的讲解

构造函数的protoType是原型对象

原型对象的属性值constructor指向构造函数

M.prototype.constructor === M;

实例的__proto__指向的是构造函数的原型对象

obj3.__proto__ === M.prototype;

8.4 instanceof

如果实例的__proto__等于构造函数的prototype或等于构造函数原型链上的prototype, 则返回true;

obj3 instanceof M === true;
obj3 instanceof Object === true;
M.prototype.__proto__ === Object.prototype;
M.__proto__ === Function.prototype;
obj3.__proto__ === M.prototype;
obj3.__proto__.constructor === M;

8.5 类的声明

第一种

function Animal(name) {
    this.name = name;
}

第二种

class Animal(name) {
    constuctor(){
        this.name = name;
    
}

实例化:new Animal()

8.6 继承

8.6.1 借助构造函数(call)
//缺点是,不能够继承父类原型上的属性和方法
function Father() {
    this.name = 'father';
    this.type = [1,2,3];
};
Father.prototype.sayHi = function() {
    console.log('hello');
}
function Son() {
    Father.call(this);
};
var son = new Son('bill');
console.log(son.name);
son.sayHi();
8.6.2 借助原型链继承
//缺点:当创建多个实例的时候,如果其中一个更改了原型链上的元素,则其他的都会更改
function Father() {
    this.name = 'father';
    this.type = [1,2,3];
}
Father.prototype.sayHi = function() {
    console.log('hello')
}
function Son() {}
Son.prototype = new Father();
var son1 = new Son();
var son2 = new Son();
son1.type.push(4)
console.log(son1.type);
console.log(son2.type)
8.6.3 组合继承
//缺点是构造函数会执行两次
function Father() {
    this.name = 'father';
    this.type = [1,2,3];
}
Father.prototype.sayHi = function() {
    console.log('hello')
}
function Son() {
    Father.call(this);
}
Son.prototype = new Father();
var son1 = new Son();
var son2 = new Son();
son1.type.push(4)
console.log(son1.type);
console.log(son2.type);
8.6.4 组合优化方式一
//缺点就是不知道son,和son2是Son还是Father的实例化
//并且Son.prototype.constructor === Father
function Father() {
    this.name = 'father';
    this.type = [1,2,3];
}
Father.prototype.sayHi = function() {
    console.log('hello')
}
function Son() {
    Father.call(this);
}
Son.prototype = Father.prototype;
var son1 = new Son();
var son2 = new Son();
son1.type.push(4)
console.log(son1.__proto__.constructor);
8.6.5 组合优化方式二
function Father() {
    this.name = 'father';
    this.type = [1,2,3];
}
Father.prototype.sayHi = function() {
    console.log('hello')
}
function Son() {
    Father.call(this);
}
Son.prototype = Object.create(Father.prototype);
Son.prototype.constructor = Son
var son1 = new Son();
var son2 = new Son();
son1.type.push(4)
console.log(son1.constructor);

//最终方式
//注意继承的时候也要加上Father.call(this);
function(Target, Origin) {
    let F = function() {};
    F.prototype = Origin.prototype;
    Target.prototype = new F();
    Target.prototype.constructor = Target;
    Target.prototype.inheritFrom = Origin;
}

9 babel

9.1 编译的原理

解析:将代码字符串解析成抽象语法树
变换:对抽象语法树进行变换操作
再建:根据变换后的抽象语法树再生成代码字符串

10 那些情况下会出现内存泄漏

闭包,意外的全局变量('use strict'),setTimeout/setTimeInterval(clearInterval) 页面中元素被移除或替换时,若元素绑定的事件仍没被移除,在IE中不会作出恰当处理,此时要先手工移除事件,不然会存在内存泄露。 没有清理的DOM元素引用 循环引用,反复重写同一个属性会造成内存大量占用

11 渲染机制类

11.1 DOCTYPE的作用

它是用来声明文档类型和DTD规范的,来验证文件的合法性。 DTD(Document type defination)是一系列的语法规则,用来定义XML和HTML的文件类型,浏览器据此来判断该使用何种协议来解析,以及切换何种模式。

11.2 种类

HTML5 和 HTML4的传统模式和严格模式,框架模式

11.3 渲染过程

解析HTML生成DOM树,解析css生成CSSOM树,然后将二者合成render树。 然后遍历渲染树,开始布局,计算每个节点,位置大小,将节点绘制到屏幕上。

11.4 什么情况下会触发浏览器的重绘与重排,怎么避免?

reflow:当页面某个部分发生了变化,影响了布局,需要重新渲染,此过程叫reflow. 触发条件:增删改dom节点时 改变窗口大小,修改字体的时候,修改样式 Repaint: 当页面元素发生变化引起repaint dom改动和css改动 避免: translate属性值来替换top/left/right/bottom的切换, scale属性值替换width/height, opacity属性替换display/visibility等等通过 document.Fragment

12 页面性能

12.1 提升页面性能的方法

资源压缩合并,减少http请求; 非核心代码异步加载; 利用浏览器缓存; 使用cdn; 预解析;

12.2 预解析

定义:浏览器会在加载网页的时候,对网页中的域名进行解析缓存,这样在用户单击网页中的链接时,就无须DNS解析了

//第一种方式,在一些高版本浏览器中,页面的所有a标签都是默认打开DNS预解析的,但若是以https开头的话
//浏览器会默认关闭此项功能,通过设置此种方式,可以强制打开。
<meta http-equiv='x-dns-prefect-control' content='on'>
//第二种方式
<link rel='dns-prefetch' href='http://www.example.abc'/>

12.3 异步加载的方式

第一:动态脚本加载

第二:defer,在HTML解析完之后执行

第三:async,在脚本加载完之后主动立即执行

12.4 缓存的分类

一:强缓存 expires: 绝对时间;catch-control:相对时间;(两个都是设置了,以后者为准)

二:协商缓存 Last-Modified If-modified-since Etag If-None-Match

13安全类

13.1 CSRF(跨域请求伪造-Cross-site request forgery)

攻击原理:在一个用户登录A网站的前提下,用户同时还浏览一个B网站,然后在B网站里面有个指向A网站的链接,然后利用cookies发起请求来攻击A网站。

防御措施:Token验证,Referer验证,隐藏令牌

13.2 xss 跨域脚本攻击

攻击原理: 向页面注入脚本(评论区)

防御措施:对输入和URL参数进行过滤

14 错误监控

14.1 分类

第一:及时运行错误,指的是代码有问题

第二:资源加载错误

14.2 如何捕获

第一:及时运行错误捕获方式:try...catch... window.onerror 第二:资源加载错误(不会冒泡到window,所以不能用window.onerror)捕获方式:

object.onerror(img,script标签上都可以加上onerror事件进行捕获)
performance.getEntries()表示加载成功的
//注意下面这种方式第三个参数一定要是true。
window.addEventListner('error', fn, true)

延伸:跨域的JS运行错误应该怎样设置才会出现详细信息

客户端:在script标签中加入crossOrigin属性 服务端:设置js资源响应头Access-Control-Allow-Origin

14.3 上报错误

第一:采用ajax上报错误;第二:(new Image()).src = 'baidu.com/test?error=…';