1. cookie,localStorage,sessionStorage
- cookie 数据始终在同源的http请求中携带,即cookie在浏览器和服务器之间传递,而sessionStoage和localStoage不会自动把数据发给服务器,仅在本地存储。
- 存储大小的限制,cookie存储大小4K,同时因为cookie每次请求都会携带,所以cookie只适合保存很小的数据,而sessionStoage和localStoage大小限制在5M或者更大
- 数据有效期不同,sessionStoage在浏览器窗口未关闭前有有效,localStoage始终有效,cookie只在设置有效期内有效
- 作用域不同,sessionStoage 只在当前页面共享,localStoage和cookie在所有同源窗口中都是共享的
2. 输入URL发生什么
- DNS 域名解析,浏览器将URL解析出相对应的IP地址及端口号
- 浏览器与服务器建立一条TCP链接
- 浏览器向服务器发送一条请求报文
- 服务器返回给浏览器一条http响应报文
- 浏览器进行渲染
- 关闭tcp链接
3. 强缓存和协商缓存
缓存是浏览器在本地磁盘对用户最近浏览的文档进行存储。
- 强缓存:不会向服务器发送请求,直接从缓存中读取资源,在chrome控制台的network选项中可以看到该请求返回200的状态码;
- 协商缓存:向服务器发送请求,服务器会根据这个请求的request header的一些参数来判断是否命中协商缓存,如果命中,则返回304状态码并带上新的response header通知浏览器从缓存中读取资源
4. 重绘(Repaint)和回流(Reflow)是啥?如何优化?
-
重绘是当节点需要更改外观而不会影响布局的,比如改变 color 就叫称为重绘。
-
回流是布局或者几何属性需要改变就称为回流。
-
回流必定会发生重绘,重绘不一定会引发回流。回流所需的成本比重绘高的多,改变父节点里的子节点很可能会导致父节点的一系列回流。
优化方案
使用 transform 替代 top 使用 visibility 替换 display: none ,因为前者只会引起重绘,后者会引发回流(改变了布局) 不要把节点的属性值放在一个循环里当成循环里的变量 不要使用 table 布局,可能很小的一个小改动会造成整个 table 的重新布局 动画实现的速度的选择,动画速度越快,回流次数越多,也可以选择使用requestAnimationFrame CSS 选择符从右往左匹配查找,避免节点层级过多 将频繁重绘或者回流的节点设置为图层,图层能够阻止该节点的渲染行为影响别的节点。比如对于 video 标签来说,浏览器会自动将该节点变为图层`
5. 同源策略是什么?
同源策略是指只有具有相同源的页面才能够共享数据,比如cookie,同源是指页面具有相同的协议、域名、端口号,有一项不同就不是同源。
6. webpack与grunt、gulp的不同?
- Grunt、Gulp是基于任务运行的工具: 它们会自动执行指定的任务,就像流水线,把资源放上去然后通过不同插件进行加工,它们包含活跃的社区,丰富的插件,能方便的打造各种工作流。
- Webpack是基于模块化打包的工具: 自动化处理模块,webpack把一切当成模块,当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。
7.webpack中loader和plugin的区别
- Loader直译为"加载器"。Webpack将一切文件视为模块,但是webpack原生是只能解析js文件,如果想将其他文件也打包的话,就会用到loader。 所以Loader的作用是让webpack拥有了加载和解析_非JavaScript文件_的能力。
- Plugin直译为"插件"。Plugin可以扩展webpack的功能,让webpack具有更多的灵活性。 在 Webpack 运行的生命周期中会广播出许多事件,Plugin 可以监听这些事件,在合适的时机通过 Webpack 提供的 API 改变输出结果。
- Loader在module.rules中配置,也就是说他作为模块的解析规则而存在。 类型为数组,每一项都是一个Object,里面描述了对于什么类型的文件(test),使用什么加载(loader)和使用的参数(options) Plugin在plugins中单独配置。 类型为数组,每一项是一个plugin的实例,参数都通过构造函数传入。
8.webpack的构建流程是什么?
Webpack 的运行流程是一个串行的过程,从启动到结束会依次执行以下流程:
- 初始化参数:从配置文件和 Shell 语句中读取与合并参数,得出最终的参数;
- 开始编译:用上一步得到的参数初始化 Compiler 对象,加载所有配置的插件,执行对象的 run 方法开始执行编译;
- 确定入口:根据配置中的 entry 找出所有的入口文件;
- 编译模块:从入口文件出发,调用所有配置的 Loader 对模块进行翻译,再找出该模块依赖的模块,再递归本步骤直到所有入口依赖的文件都经过了本步骤的处理;
- 完成模块编译:在经过第4步使用 Loader 翻译完所有模块后,得到了每个模块被翻译后的最终内容以及它们之间的依赖关系;
- 输出资源:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的 Chunk,再把每个 Chunk 转换成一个单独的文件加入到输出列表,这步是可以修改输出内容的最后机会;
- 输出完成:在确定好输出内容后,根据配置确定输出的路径和文件名,把文件内容写入到文件系统。
9.webpack的plugins和loaders的实现原理?
Loader像一个"翻译官"把读到的源文件内容转义成新的文件内容,并且每个Loader通过链式操作,将源文件一步步翻译成想要的样子。 编写Loader时要遵循单一原则,每个Loader只做一种"转义"工作。 每个Loader的拿到的是源文件内容(source),可以通过返回值的方式将处理后的内容输出,也可以调用this.callback()方法,将内容返回给webpack。 还可以通过 this.async()生成一个callback函数,再用这个callback将处理后的内容输出出去。 此外webpack还为开发者准备了开发loader的工具函数集——loader-utils。 相对于Loader而言,Plugin的编写就灵活了许多。webpack在运行的生命周期中会广播出许多事件,Plugin 可以监听这些事件,在合适的时机通过 Webpack 提供的 API 改变输出结果
10. 如何提高webpack的构建速度?
- 多入口情况下,使用CommonsChunkPlugin来提取公共代码
- 通过externals配置来提取常用库
- 利用DllPlugin和DllReferencePlugin预编译资源模块 通过DllPlugin来对那些我们引用但是绝对不会修改的npm包来进行预编译,再通过
- DllReferencePlugin将预编译的模块加载进来。
- 使用Happypack 实现多线程加速编译
- 使用webpack-uglify-parallel来提升uglifyPlugin的压缩速度。 原理上webpack-uglify-parallel采用了 多核并行压缩来提升压缩速度
- 使用Tree-shaking和Scope Hoisting来剔除多余代码
11. AMD和CMD的区别?
最明显的区别就是在模块定义时对依赖的处理不同 AMD推崇依赖前置,在定义模块的时候就要声明其依赖的模块 CMD推崇就近依赖,只有在用到某个模块的时候再去require
12. 说一下你了解CSS盒模型
-
基本概念 标准模型 border margin padding content IE模型 border margin padding content
-
标准模型和IE模型的区别 计算width height 的不同 标准模型: width height 是content的高度 宽度 IE模型: width height 包含padding border部分
-
css如何设置两种模型 标准: box-sizing: content-box IE模型: box-sizing :border-box
-
js如何获取盒子模型对应的宽和高
document.style.width/height document.currentStyle.width/height window.getComputedStyle(dom).width
- BFC
块级格式化上下文,解决边距重叠
原理:
1)BFC垂直方向发生重叠 。
2)BFC的区域不会与浮动元素的box重叠
3)BFC是一个独立的容器,外面的元素不会影响里面的元素 。
4)计算BFC高度,浮动元素也会参与计算
Javascript部分
1. 谈谈对闭包的理解,闭包的用途,闭包的缺点
- 闭包是指有权访问另外一个函数作用域中的变量的函数
- 闭包的用途
- 设计私有的方法和变量。
- 匿名函数最大的用途是创建闭包,并且还可以构建命名空间,以减少全局变量的使用。从而使用闭包模块化代码,减少全局变量的污染
- 闭包的缺点
- 闭包会使得函数中的变量都被保存在内存中,滥用闭包可能导致内存泄漏。解决方法是在函数退出之前,将不使用的局部变量全删了。
- 闭包会在父函数外部,改变父函数内部变量的值。
2. 讲一讲js里面的异步操作有哪些?
回调函数
事件监听
观察者模式,也叫订阅发布模式
promise
async/await
generator 函数
3. 什么是函数节流和函数去抖?
- 函数去抖 debounce: 当调用函数n秒后,才会执行该动作,若在这n秒内又调用该函数则将取消前一次并重新计算执行时间。
var debounce = function(delay, cb) {
var timer;
return function() {
if (timer) clearTimeout(timer);
timer = setTimeout(function() {
cb();
}, delay);
}
}
-
函数节流 throttle: 函数节流的基本思想是函数预先设定一个执行周期,当调用动作的时刻大于等于执行周期则执行该动作,然后进入下一个新周期
var throttle = function(delay, cb) { var startTime = Date.now(); return function() { var currTime = Date.now(); if (currTime - startTime > delay) { cb(); startTime = currTime; } } }
### 4. script标签如何异步加载?
* 默认情况下,浏览器是同步加载 JavaScript 脚本,即渲染引擎遇到 script 标签就会停下来,等到执行完脚本,再继续向下渲染。如果是外部脚本,还必须加入脚本下载的时间。如果脚本体积很大,下载和执行的时间就会很长,因此造成浏览器堵塞,用户会感觉到浏览器“卡死”了,没有任何响应。
```javascript
<script src="path/to/myModule.js" defer></script>
<script src="path/to/myModule.js" async></script>
- defer与async的区别是:
1. defer要等到整个页面在内存中正常渲染结束(DOM 结构完全生成,以及其他脚本执行完成),才会执行;async一旦下载完,渲染引擎就会中断渲染,执行这个脚本以后,再继续渲染。一句话,defer是“渲染完再执行”,async是“下载完就执行”。
2. 另外,如果有多个defer脚本,会按照它们在页面出现的顺序加载,而多个async脚本是不能保证加载顺序的。
5. 讲一下let、var、const的区别,谈谈如何冻结变量
- var 没有块级作用域,支持变量提升。
- let 有块级作用域,不支持变量提升。不允许重复声明,暂存性死区。
- const 有块级作用域,不支持变量提升,不允许重复声明,暂存性死区。声明一个变量一旦声明就不能改变,改变报错。const保证的变量的内存地址不得改动。如果想要将对象冻结的话,使用Object.freeze()方法
6. 谈谈js事件循环机制
- 程序开始执行之后,主程序则开始执行 同步任务,碰到 异步任务 就把它放到任务队列中,等到同步任务全部执行完毕之后,js引擎便去查看任务队列有没有可以执行的异步任务,将异步任务转为同步任务,开始执行,执行完同步任务之后继续查看任务队列,这个过程是一直 循环 的,因此这个过程就是所谓的 事件循环,其中任务队列也被称为事件队列。通过一个任务队列,单线程的js实现了异步任务的执行,给人感觉js好像是多线程的。
7.箭头函数和普通函数的区别是什么?
- 普通函数this:
- this总是代表它的直接调用者。
- 在默认情况下,没找到直接调用者,this指的是window。
- 在严格模式下,没有直接调用者的函数中的this是undefined。
- 使用call,apply,bind绑定,this指的是绑定的对象。
- 箭头函数this:
- 在使用=>定义函数的时候,this的指向是 定义时所在的对象,而不是使用时所在的对象;
- 不能够用作构造函数,这就是说,不能够使用new命令,否则就会抛出一个错误;
- 不能够使用 arguments 对象;
- 不能使用 yield 命令;
8. 函数柯里化理解
- 只传递给函数一部分参数来调用它,让它返回一个函数去处理剩下的参数。
- 用途:1.延迟计算;2.参数复用;3.动态生成函数
9. new 内部发生了什么过程?可不可以手写实现一个 new 操作符?
- 创建一个新的对象
- 这个对象的__proto__ 指向原函数的prototype属性
- 将这个新对象绑定到这个函数的this上
- 返回新对象,如果这个函数没有返回其他对象
10. new/字面量 与 Object.create(null) 创建对象的区别?
new 和 字面量创建的对象的原型指向 Object.prototype,会继承 Object 的属性和方法。 而通过 Object.create(null) 创建的对象,其原型指向 null,null 作为原型链的顶端,没有也不会继承任何属性和方法。
框架类 (React)
1. 为什么虚拟dom会提高性能
- 虚拟dom相当于在js和真实dom中间加了一个缓存,利用dom diff算法避免了没有必要的dom操作,从而提高性能,虚拟DOM本质上是JavaScript对象,是对真实DOM的抽象,状态变更时,记录新树和旧树的差异,最后把差异更新到真正的dom中
具体实现步骤如下:
- 用 JavaScript 对象结构表示 DOM 树的结构;然后用这个树构建一个真正的 DOM 树,插到文档当中;
- 当状态变更的时候,重新构造一棵新的对象树。然后用新的树和旧的树进行比较,记录两棵树差异; 把2所记录的差异应用到步骤1所构建的真正的DOM树上,视图就更新了
前端的性能优化和安全
1. 常见的网站漏洞有哪些
有跨站脚本攻击(XSS)、跨站请求伪造(CSRF)、点击劫持、SQL注入、DDOS攻击、DNS劫持
2. 讲讲CSRF和XSS区别
XSS:跨站点攻击。xss攻击的主要目的是想办法获取目标攻击网站的cookie,因为有了cookie相当于有了session,有了这些信息就可以在任意能接进互联网的PC登陆该网站,并以其他人的身份登陆做破坏。
CSRF 跨站点伪装请求
xss和csrf有哪些防御方式
如何防范 XSS 攻击: 1、对输入的字符串做长度限制; 2、对用户的输入进行过滤,如对& < > " ' /等进行转义; 3、获取用户的输入,不用innerHtml,用innerText.
如何防范CSRF攻击: 1、验证 HTTP Referer 字段; 2、在请求地址中添加 token 并验证; 3、在 HTTP 头中自定义属性并验证。
HTML5
1. Html5语义化与新特性
1、什么是HTML语义化?
- 表示选择合适的标签(语义化标签)便于开发者阅读和写出更优雅的代码
2、为什么要使用语义化标签? 在没有CSS样式的情况下,页面整体也会呈现很好的结构效果 更有利于用户体验 更有利于搜索引擎优化 代码结构清晰,方便团队开发与维护
3、 HTML5新特性有哪些? 语义化标签 音视频处理 canvas / webGL history API requestAnimationFrame 地理位置 webSocket
DOM事件类
1. 基本概念:DOM事件的级别
DOM0:element.onlick = function(){}
DOM2:element.addEventListener('click', function(){},false)
DOM3:element.addEventListener('keyup',function(){},false)
2. DOM事件模型
冒泡事件是从内向外 捕获是从外向内======document->html->body->div
3. DOM事件流
一个完整的事件流分为三个阶段:捕获-》目标阶段-》冒泡=========事件通过捕获到达目标元素再从目标元素通过冒泡上传到元素 捕获:window->document->html->body->......->目标元素
对象深浅拷贝
1. 浅拷贝
创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址 ,所以如果其中一个对象改变了这个地址,就会影响到另一个对象
Object.assign(target, ...sources)
2. 深拷贝
将一个对象从内存中完整的拷贝一份出来,从堆内存中开辟一个新的区域存放新对象,且修改新对象不会影响原对象
最简单的方法就是JSON.parse(JSON.stringify()),但是这种拷贝方法不可以拷贝一些特殊的属性(例如正则表达式,undefine,function)
```javascript
function deepCopyTwo(obj) {
let objClone = Array.isArray(obj) ? [] : {};
if (obj && typeof obj == 'object') {
for (const key in obj) {
//判断obj子元素是否为对象,如果是,递归复制
if (obj[key] && typeof obj[key] === "object") {
objClone[key] = deepCopyTwo(obj[key]);
} else {
//如果不是,简单复制
objClone[key] = obj[key];
}
}
}
return objClone;
}
```
bind、call、apply用法及区别
相同点: 三个函数的作用就是改变this的指向,将函数绑定到上下文中; 不同点: 三个函数的语法不同
```javascript
fun.call(thisArg[, arg1[, arg2[, ...]]])
fun.apply(thisArg, [argsArray])
var bindFn = fun.bind(thisArg[, arg1[, arg2[, ...]]])
bindFn()
```
目前JS解决异步的方案有哪些
- 回调函数
- 事件监听
- 发布-订阅
- Promise
- Generator
- Async/Await
创建对象有几种方法
// 第一种:字面量
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)
浏览器篇
1.跨域解决方案
1) jsonp
- 原理 利用script标签没有跨域限制的漏洞,网页可以得到从其他来源动态产生的 JSON 数据。JSONP请求一定需要对方的服务器做支持才可以
- JSONP和AJAX对比 JSONP和AJAX相同,都是客户端向服务器端发送请求,从服务器端获取数据的方式。但AJAX属于同源策略,JSONP属于非同源策略(跨域请求)
- JSONP优缺点 JSONP优点是简单兼容性好,可用于解决主流浏览器的跨域数据访问的问题。缺点是仅支持get方法具有局限性,不安全可能会遭受XSS攻击。