整理面经·JS·Vue·ES6
JS方面
1.浏览器的缓存机制(强缓存和协商缓存)
答:浏览器在加载资源的时候会根据这个资源的一些http header 判断是否命中强缓存 如果命中 那个浏览器将不会去请求服务器,而是直接从缓存中加载这个资源。如果强缓存没有命中 浏览器会发送一个请求到服务器 浏览器依据资源的另一些 http header 验证是否命中协商缓存。 如果未命中,则向服务器发送请求,加载数据。
总结:
根据 http header 判断 ,
先判断是否命中强缓存(数据在缓存中)命中则不请求服务器 直接从缓存返回
强缓存未命中请求服务器进行协商缓存 浏览器根据 其他 http header 验证是否命中协商缓存 命中不会返回数据 而是返回 http header 让客户端自己从缓存中缓存
协商缓存未命中 则请求服务器资源
2. new的过程
4.原型链
什么是原型链:
数组、对象、函数 都有一个proto属性(隐式原型) 属性值是一个对象
5.闭包
(1)可以读取到函数内部的变量
(2)就是让这些变量的值始终保持在内存中。
6.数组去重的方法
(1)indexOf 遍历数组的每一个元素 在新数组里的角标是否小于 0 小于则添加 大于继续
(2)set() 新建一个 Map 把没有的元素的value设置成1
(3)filter () 过滤器 这个函数自动把每一个元素放进去 通过回调函数判断
(4)用ES6 里的 Set()
7.前端如何优化性能
1.减少http请求次数
2.减少DNS查询次数
3.避免页面跳转
4.缓存Ajax
5.延迟加载
6.提前加载
7.减少DOM元素数量
8.根据域名划分内容
9.减少iframe数量
10.避免404
8.get和 post区别
1. get在浏览器回退时是无害的,而post会再次请求
2 .get产生的url地址可以被收藏,而post不会
3. get请求会被浏览器主动缓存,而post不会,除非手动设置
4. get请求只能进行url编码,而post支持多种编码方式
5. get请求参数会被完整保留在浏览历史记录里,而post中的参数不会被保留
6. get 请求在url中传送的参数有长度限制,而post没有
7. 对参数的数据类型,get只接受ascll字符,而post没有限制
8. get比post更安全,因为参数直接暴露在url上,所以不能用来传递敏感信息
9. get参数通过url传递,poet放在request body中
(记不住全部的,重点回答出1,2,5,6,9这几点即可)
get请求能被保留在浏览器历史记录里,post不能,这样get就可以被收藏, 可以被自动缓存,get有长度限制 post没有长度限制 get能拼参数 暴露在浏览器上, 所以get参数是在url上 post在request body上
9.http状态码
网址:https://www.cnblogs.com/yzxing/p/9665109.html
1:100(信息类):表示接收到请求并且继续处理
2:200(响应成功类):表示动作被成功接收、理解和接受
3:300(重定向类):为了完成指定的动作,必须接受进一步处理
4:400(客户端错误类):请求包含错误语法或不能正确执行
5:500(服务端错误类):服务器不能正确执行一个正确的请求
10.对象深拷贝
JSON.parse(JSON.stringufy( arr ))
用三点 var arr2 = [ ... arr1 ] 两个数组相等 但是不三等 === 即内存地址不相同
11.cookie 和 session 区别:
cookie是保存在本地 有长度限制
session保存在服务器 访问增多 安全性高
12.TCP 和 UDP 的区别
TCP 是一个稳定可靠地传输协议, 只能一对一进行传递,UDP 可以一对一 一对多 多对一 多对多
TCP 是面向连接的(像 打电话) UDP 是不需要连接的 (像 送快递)
TCP 面向字节流 UDP 面向报文
TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,不保证可靠交付
TCP 首部开销 20字节 UDP 8字节
TCP是全双工通道 UDP是不可靠通道
13. js里的this是什么?举例每种说明
在一般函数中 指的全局对象
在构造函数中 指的当前函数对象
在对象方法中 指的上级对象
14. localStorage 和 sessionStorage 的区别 和 用法
1.两者和cookie都是本地存储 cookie 存储大小是 4k localStorage 大小是 5M
2.localstorage 保存在 本地 永久有效
3.sessionStorage 关闭页面就失效 刷新页面还是有效
保存方法
// 保存数据到 sessionStorage
sessionStorage.setItem('key', 'value');
// 从 sessionStorage 获取数据
let data = sessionStorage.getItem('key');
// 从 sessionStorage 删除保存的数据
sessionStorage.removeItem('key');
// 从 sessionStorage 删除所有保存的数据
sessionStorage.clear();
15. filter 是啥 过滤器
16. animation
主轴和侧轴是通过flex-direction确定的
如果flex-direction是row或者row-reverse,那么主轴就是justify-contain
如果flex-direction是column或者column-reverse,那么主轴就是align-items
18、如何判断变量类型?typeof、instance of、constructor、Object.prototype.toString.call()。只用前2个会有局限性
typeof:在判断变量类型的时候比较适合用来处理基本数据类型,如果是引用类型的值 typeof恐怕就心有余而力不足了。
instanceof:会根据_proto_一层层往上找,找到匹配的数据类型就会输出true 找到null找不到才输出false 该运算符用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性。
constructor: 为了避免_propo_的一层层找 我们引用constructor方法 此属性返回对创建此对象的数组函数的引用
Object.prototype.toString.call():在js中该方法可以精准的判断对象类型,也是推荐使用的方法。可以判断基本数据类型:
typeof( a ) | a instanceof b | a.constructor == Array | Obeject.prototype.toString.call()
19、call,apply,bind的不同? bind返回的是一个函数,而apply会立即执行
call、apply与bind区别:前两个可以自动执行,bind不会自动执行,需要手动调用
call、bind与apply区别:前两个都有无数个参数,apply只有两个参数,而且第二个参数为数组
20、跨域解决办法:document.domain, location.hash, window.name, window.postMessage, JSONP, WebSocket, CORS 。
CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin reso
urce sharing)。
由 XMLHttpRequest 或 Fetch 发起的跨域 HTTP 请求。
document.domain:若两个源所用协议、端口一致,主域相同而二级域名不同的话,可以借鉴该方法解决跨域请求。
JSONP:全称 JSON with Padding,是使用 AJAX 实现的请求不同源的跨域
jsonp虽然很简单,但是有如下缺点:
1)安全问题(请求代码中可能存在安全隐患)
2)要确定jsonp请求是否失败并不容易
XMLHttpRequest :
abort():停止当前请求;
getAllResponseHeaders():把HTTP请求的所有相应首部作为键/值对返回;
getResponseHeader("header"):返回指定首部的串值;
open("method", "url"):建立对服务器的调用;
send(content):向服务器发送请求;
setRequestHeader("header", "value"):把指定首部设置为所提供的值,在设置任何首部之前必须先调用open();
web sockets:
21、原生ajax的步骤:记忆不深。
原生:oAjax.open("GET", "a.txt?t='+new Date().getTime()", true);//加上t='+new Date().getTime()"
oAjax.send();
//客户端和服务器端有交互的时候会调用onreadystatechange
oAjax.onreadystatechange = function () {
if (oAjax.readyState == 4) {
if (oAjax.status == 200)//判断是否成功,如果是200,就代表成功
{
alert("成功" + oAjax.responseText);//读取a.txt文件成功就弹出成功。后面加上
oAjax.responseText会输出a.txt文本的内容
}
else {
alert("失败");
}
}
ajax的jquery写法:
$.ajax({
url: "", //请求的url地址 dataType: "json", //返回格式为json
async: true, //请求是否异步,默认为异步,这也是ajax重要特性
data: { }, //参数值 type: "GET", //请求方式
processData: false, //对表单data数据是否进行序列化
contentType: false, //dataType设置你收到服务器数据的格式
beforeSend: function () {
//请求前的处理
},
success: function (req) {
//请求成功时处理
},
complete: function () {
//请求完成的处理
},
error: function () {
//请求出错处理
}
});
22、箭头函数与普通函数的区别:回答不太好 (建议自己根据文档操作一下this指向的问题)
(1)函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
(2)不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。
(3)不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。
(4)不可以使用yield命令,因此箭头函数不能用作 Generator 函数。
23、vue keep-alive、vue router路由模式、vuex常用命令、active生命周期
keep-alive: 组件实例能够被在它们第一次被创建的时候缓存下来
vue router路由模式:
state gettters mutations action modules
active生命周期: 创建 挂载 更新 删除
ES6、7等新特性学习不深,建议花时间学习一下阮一峰的ECMAScript 6 入门。如常用的结构赋值、模板字符串、class、async、module等。 框架方面库建议选择react、vue、angular中的一个深入学习使用。
也可以了解一下现在前端的发展方向https://github.com/kamranahmedse/developer-roadmap。
24. 事件委托,使用事件委托有什么好处?
就是让别人来做,这个事件本来是加在某些元素上的,然而你却加到别人身上来做,完成这个事件。
也就是:利用冒泡的原理,把事件加到父级上,触发执行效果。
好处呢:1,提高性能。
25.map 和 for 循环的区别
1)map有返回值,不改变原数组 for无返回值,改变原数组
2)没有办法终止或者跳出forEach()循环,除非抛出异常,所以想执行一个数组是否满足什么条件,返回布尔值,可以用一般的for循环实现,或者用Array.every()或者Array.some();
3)map会快一点 for会慢一点
26.二叉树广度优先和深度优先(非计算机专业不用了解)
27.递归算法(非计算机专业不用了解)
28.maps映射 set 集合
29.安全问题
30.计算属性是怎么实现缓存的
31.Nginx反向代理
32.web语义化 html语义化
33.超出部分变成省略号
white-space: nowrap;/*内容超宽后禁止换行显示*/
overflow: hidden;/*超出部分隐藏*/
text-overflow:ellipsis;/*文字超出部分以省略号显示*/
Vue方面
1. foreach forin forof 的区别
1)for 和 for...in 是针对数组下标的遍历 通常遍历json 和 数组 按下标获取元素
2)forEach 及 for...of 遍历的是数组中的元素 通常遍历数组,取出数据每个元素 遍历json报错
3)for...in 在遍历数组的时候 对于 ,, 未定义元素 会跳过
for...of 在遍历数组的时候 就会取出一个空元素
2.嵌套路由怎么定义
在 Vuerouter 的参数中使用 children 配置 , 这样就可以很好的实现路由嵌套。
在路由里重定向 { path redirect component children }
3.Vue 双向绑定的实现原理:
vue的双向绑定采用ES5 里的 Object.defineProperty() 方法。 监控对数据的操作, 从而可以自动触发数据同步。并且,由于是对不同的数据进行变更,可以精确的将变更发送给绑定的视图,而不是将所有的数据一一遍历。
defineProperty参数 1.对象 2.属性key 3 { configureable Enumerable writer value }
configureable能否通过delete重新定义 Enumerable能否通过for-in遍历
writer能否写这个属性 value 第2个属性的value值
除此之外,里面还有 setter 和 getter 取值、给对象赋值的时候触发
4.使用 Vuex 只需执行 Vue.use(Vuex),并在 Vue 的配置中传入一个 store 对象的示例,store 是如何实现注入的?
Vue.use(Vuex) 方法执行的是 install 方法,它实现了 Vue 实例对象的 init 方法封装和注入,使传入的 store 对象被设置到 Vue 上下文环境的$store 中。因此在 Vue Component 任意地方都能够通过 this.$store 访问到该 store。
5.state 内部支持模块配置和模块嵌套,如何实现的?
在 store 构造方法中有 makeLocalContext 方法,所有 module 都会有一个 local context,根据配置时的 path 进行匹配。所以执行如 dispatch('submitOrder', payload)这类 action 时,默认的拿到都是 module 的 local state,如果要访问最外层或者是其他 module 的 state,只能从 rootState 按照 path 路径逐步进行访问。
ES6 (尽量去理解吧)
1. less 的一些应用语法:
1)复制
2)定义样式class
3)嵌套 父 套 子
4)嵌套 冒泡
5)延迟加载
2.vue中的 is 属性 :
is 是用来绑定组件 <li is = " 组件名 " > 除此以外 还可以绑定属性
:is <component :is = " data 属性变量 ">
3. ES6 的解构方法
数组解构 嵌套结构 函数传参解构 for循环解构
4. ... 扩展运算符 可以用来深拷贝数组 var arr2 = [ ... arr1 ] arr2 与 arr1 全等但是不三等 即不同内存地址
... rest 运算符 把逗号隔开的值组成一个数组 (1,2,3,4)实参 ( ... args)形参
5.super 关键字 初始化构造函数的时候应用 指向当前对象的原型对象
6. set : 类似为 数组 但是成员的值都是唯一的, 没有重复的值
set的添加方法: var s = new Set() s.add(1) ;
s.size() 查询长度 s.delete(value) 删除一个元素,返回布尔,成功否
s.has(value) 查询是否存在 s.clear() 清空
set 可以接受一个数组 自动过滤掉重复元素
应用: 去重字符串 [...new Set('ababbc')].join('')
6.箭头函数和普通函数的区别:
1)箭头函数导致this总是指向函数定义生效时所在的对象
2)不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。
3)不可以使用arguments对象,该对象在函数体内不存在。
4)不可以使用yield命令,因此箭头函数不能用作 Generator 函数。
7.Promise.all 方法 :
const p = Promise.all([p1, p2, p3]);
promise.all() 方法接受一个数组作为参数, p1、p2、p3都是 Promise实例 另外,Promise.all()方法的参数可以不是数组,但必须具有 Iterator 接口,且返回的每个成员都是 Promise 实例。
只有 p1 p2 p3 全部变成 fulfilled (成功) p 才能返回到回调函数
如果有一个被reject 那么 p 就是 reject 然后一个被reject 的 返回值 返回到p 的回调函数
对比 Promise.race() 方法:
all 方法 是根据每一个 p 的 成功失败来 确定 返回的状态--- 都成功则成功 一失败则失败
race 方法则是 根据率先改变状态的 p 的状态来 返回状态
8. Iterator 的作用有三个:一是为各种数据结构,提供一个统一的、简便的访问接口;二是使得数据结构的成员能够按某种次序排列;三是 ES6 创造了一种新的遍历命令for...of循环,Iterator 接口主要供for...of消费。
9. Generator : 是ES6 提供了一种异步编程解决方案 , 它和Iterator有着相同的选择器 next ()
Generator 有两个特征 :
1. function 和 函数名 之间有一个 * 号 这个 星号现在可以放在任何位置
2. 函数体内使用 yield 表达式 定义不同的内部状态
里面的 yield 可以 通过 next 调用 返回 { value : '' , done : false }
10. async 和 await
对比 Generator 发现 async 就是把 function后的 * 变成了 async , 把 yield 变成了 await
四点改进:
1)内置执行器 不需要next了
2)返回值是 Promise
3)比 * 和 yield 更好理解
await 后面是 一个 promise 对象
async function getStockPriceByName(name) {
const symbol = await getStockSymbol(name);
console.log('getStockSymbol1');
const stockPrice = await getStockPrice(symbol);
console.log('getStockPrice1')
return stockPrice;
}
function getStockSymbol(){
setTimeout(()=>{
console.log('getStockSymbol');
},0)
}
function getStockPrice(){
console.log('getStockPrice')
}
getStockPriceByName('goog').then(function (result) {
console.log(result);
});
11. class 类
和 java里的 类类似 都可以 在里面创建方法 通过实例化 去使用里面的函数
class 类里有一个默认方法 constructor 他是直接指向类的本身的 构造函数
Point.prototype.constructor === Point // true
方法:
1)点 hashasOwnProproty 检测是否含有实例对象的自身属性 this.x this.y的 x.y
实例对象的方法是false 因为他是定义在 类上
2)改变class类里方法内部的this指向
1>构造函数中 this.printName = this.printName.bind(this);
2>构造函数中 this.getThis = () => this; 箭头函数
注意:
1)实例化的两个对象 原型 ===
2)有 get 和 set 方法
3)var Myclass = class Me { getName() { return Me.name } }类也可以使用表达式的形式定义
在 Class 外部,这个类只能用MyClass引用
4) ** 不存在变量提升 内部是严格模式 name属性 Generation方法
5) 静态方法 +static ,就表示该方法不会被实例继承,而是直接通过类来调用 继承 私有公有 a 和 _a
12. Module
1)模块功能主要由两个命令构成:export和import。export命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能。
2)import { area, circumference } from './circle'; import * as circle from './circle';
3)export default 模块指定默认输出