面试题
axios和ajax的区别
axios是通过promise实现对ajax技术的一种封装
axios可以运行nodejs里边,ajax只能在js中使用
拦截请求和响应(Interceptors拦截器)
axios可以并发请求
h5+css3新特性有哪些
h5的新特性:
1.增加了语义化内容的元素,如header,footer,artical,section,nav
2.增加了用于绘画的canvas元素以及svg元素等
3.增加了用于多媒体的video和audio元素
4.增加了localstorage和secssionStorage
5.HTML5拥有更有效的服务器推送技术,Server-Sent Event和WebSockets就是其中的两个特性,这两个特性能够帮助我们实现服务器将数据“推送”到客户端的功能
CSS3的新特性:
1.新增属性选择器,伪元素选择器
2.新增边框圆角,边框阴影,文字阴影,2d,3d转换,渐变,动画等效果
LocalStorage,SessionStorage,Cookie的区别以及使用的场景
储存方式 | 储存大小 | 清除 | 使用场景 |
---|---|---|---|
cookie | 4K左右 | 可以设置失效时间 | 判断用户是否登陆过网站,记住密码等 |
localStorage | 5M左右 | 除非被清除或者卸载浏览器,否则永久保存; | 适合长期保存在本地的数据,比如说夜间模式,主题模式等 |
sessionStorage | 5M左右 | 仅在当前会话下有效,关闭页面或浏览器后被清除 | 网上商城中的购物车,ajax的数据缓存 |
axios的二次封装
- 接口放在一起,统一处理
- 配置开发和生产环境地址
- 通过请求和响应拦截器,对请求头进行设置,添加token等字段,添加中英文设置
- 全局loading处理
- 请求超时的时候发送多次请求,限制快速点击,中断请求等等
- 根据后端状态码,添加错误处理提示,因为这个是国际化的,所以我们当时是封装了一个模块去处理
websocket
websocket--http协议的一个补丁,支持长久连接。http协议的服务器被动性,只有服务器不断发送请求,服务器才会返回response;而websocket协议的服务器具有主动性,只要客服端发起一次请求,就会一直连接,而服务器只要有response就可以主动给返回。
缺点:网络通信问题,若是中间网络信号等问题,互动通信的信息没有抵达接受方,由于是长连接,所以无法判断是否数据丢失。
call,apply,bind的区别
- 都是用来改变函数的this对象的指向的;
- 第一个参数都是this要指向的对象;
- 都可以利用后续参数传参,apply的第二个参数是一个参数数组,call的第二个及其以后的参数都是数组里面的元素,就是说要全部列举出来。
- bind是返回对应函数,便于稍后调用,apply,call是立即调用。
vue 组件通信
父-子 props
子-父 $emit $on
兄弟 vuex
路由传参
父组件调用子组件方法
ref $refs
子组件调用父组件方法
- this.$parent
- 子组件里用$emit向父组件触发一个事件,父组件监听这个事件就行了。
- 父组件把方法传入子组件中,在子组件里直接调用这个方法
闭包(什么是闭包?什么情况下用到闭包?有什么优缺点?为什么不被垃圾回收机制回收?什么是垃圾回收机制?)
闭包就是函数内嵌套函数
在函数中定义的变量, 被内层函数应用后, 不会被垃圾将回收机制回收
优点: 可以使用函数内的变量, 并且不被回收 缺点: 过多使用, 会对内存造成压力
因为他们相互调用,所以不会被垃圾回收机制回收。
不被调用的方法或变量,就不会被垃圾回收机制回收。
跨域的解决方法
-
JSONP
利用src不受同源策略的限制, 可以访问不同源的资源
而script标签期望请求到一段JS代码
所以利用script标签去请求不同源的后端接口
接口返回一段前端函数调用的JS代码, 并把数据作为参数传入 前端通过函数的处理逻辑获取数据 jsonp理论上不属于ajax请求 -
CORS
后端接口设置响应偷, 为指定用户或所有用户开发访问权限 -
服务器代理
因为后端访问不受同源策略的影响, 所以可以使用同源的服务器去访问不同源的资源 在把获取到的资源返回给前端 -
sorket
sorket没有跨域问题, 可以使用sorket进行前后端数据交换
原型链
当访问一个对象的某个属性时,会先从该函数本身属性上找,如果没有找到,则会在他的 _ proto _隐式属性(即构造函数的prototype)上去找,如果还没有找到的话,则就会再去prototyep的 _ proto _ 中去找,这样一层一层向上查找就会形成一个链式结构,就称之为原型链。
DNS是什么,解析域名的原理,过程是什么?
DNS( Domain Name System)是“域名系统”
DNS通过域名解析系统解析找到了对应的IP地址,域
具体过程如下:
- 客户机提出域名解析请求,并将该请求发送给本地的域名服务器.
- 当本地的域名服务器收到请求后,就先查询本地的缓存,如果有该纪录项,则本地的域名服务器就直接把查询的结果返回.
- 如果本地找不到:
①用户主机上运行着DNS的客户端,就是我们的PC机或者手机客户端运行着DNS客户端了
②浏览器将接收到的url中抽取出域名字段,就是访问的主机名,比如http://www.baidu.com/
③DNS客户机端向DNS服务器端发送一份查询报文,报文中包含着要访问的主机名字段(中间包括一些列缓存查询以及分布式DNS集群的工作)
④该DNS客户机最终会收到一份回答报文,其中包含有该主机名对应的IP地址
⑤一旦该浏览器收到来自DNS的IP地址,就可以向该IP地址定位的HTTP服务器发起TCP连接
介绍一下vue
mvvm , 单页面应用
有指令,支持双向绑定
组件化
面向对象
生命周期
vue-cli vuex vue-router
通过vue-cli搭建项目
路由
组件通信 props $emit $on vuex
vue ui
虚拟Dom及其作用/好处
虚拟DOM其实就是用JS来模拟DOM结构,把DOM的变化操作放在JS层来做,尽量减少对DOM的操作,然后对比前后两次的虚拟DOM的变化,只重新渲染变化了的部分,而没有变化的部分则不会重新渲染。
1.避免大量无谓的计算量,解决浏览器性能问题
2.操作虚拟dom即js对象远快于操作真实dom
引用数据类型和基础书类型的区别
常见的基本数据类型:Number、String 、Boolean、Null和Undefined。基本数据类型是按值访问的,因为可以直接操作保存在变量中的实际值。
引用类型数据:也就是对象类型Object type,比如:Object 、Array 、Function 、Data等。
基本数据类型,栈内存保存的是值。引用数据类型栈内存中保存的是key,内容放在堆内存中。
字符串有哪些方法
lenght,indexof,search
- String.fromCodePoint()
- String.raw()
- 实例方法:codePointAt()
- 实例方法:normalize()
- 实例方法:includes(), startsWith(), endsWith()
- 实例方法:repeat()
- 实例方法:padStart(),padEnd()
- 实例方法:trimStart(),trimEnd()
- 实例方法:matchAll()
数组有哪些方法?
isArray,forEach,map,filter,reduce,every,set
- 扩展运算符
- Array.from()
- Array.of()
- 数组实例的 copyWithin()
- 数组实例的 find() 和 findIndex()
- 数组实例的 fill()
- 数组实例的 entries(),keys() 和 values()
- 数组实例的 includes()
- 数组实例的 flat(),flatMap()
- 数组的空位
- Array.prototype.sort() 的排序稳定性
undefined和null区别
underfined :没有定义
null:定义了,未赋值
jQuery获取兄弟节点
$('#id').siblings() 当前元素所有的兄弟节点
$('#id').prev() 当前元素前一个兄弟节点
$('#id').prevAll() 当前元素之前所有的兄弟节点
$('#id').next() 当前元素之后第一个兄弟节点
$('#id').nextAll() 当前元素之后所有的兄弟节点
link和@import的区别
两者都是外部引用CSS的方式,但是存在一定的区别:
区别1:link是XHTML标签,除了加载CSS外,还可以定义RSS等其他事务;@import属于CSS范畴,只能加载CSS。
区别2:link引用CSS时,在页面载入时同时加载;@import需要页面网页完全载入以后加载。
区别3:link是XHTML标签,无兼容问题;@import是在CSS2.1提出的,低版本的浏览器不支持。
区别4:link支持使用Javascript控制DOM去改变样式;而@import不支持。
同步,异步,延时加载
同步:一步步加载
异步:同时加载
延时加载:等到要用或者空闲时在加载
做项目的思路
看设计图,选择框架,选择ui
搭建框架,引入ui,定制项目规范(公共组件,模块,页面放哪里,命名方式),设计公共css模块
配置路由,axios
页面绘制和接口(封装公共组件,模块)
a标签的优先级
href 优先于点击事件
如何用js把一个很大的图片压缩
我们用的是一个叫compressor.js的插件去压缩的,没有自己写,就像我们项目用到了上传图片组件,就会去压缩图片
如何监听全局的异常,包括浏览器崩溃,服务器问题等等
errorHandler
vue如何定义全局变量
- 挂载原型链上
- 全局变量模块
防抖和节流
- 防抖(debounce)
所谓防抖,就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。 - 节流(throttle)
所谓节流,就是指连续触发事件但是在 n 秒中只执行一次函数。节流会稀释函数的执行频率。
对于节流,一般有两种方式可以实现,分别是时间戳版和定时器版。
解释单向数据绑定和双向数据绑定以及他们之前的区别
-
单向数据绑定:
是先把模板写好,然后把数据和模板整合一起形成html,然后把html代码插入文档流里面。
缺点:Html代码一旦生成完以后,就没有办法再变了,如果有新的数据来了的话,只能去掉原来的HTML代码,再重新的数据和模板一起整合到文档流中。简单来说就是dom操作直接改变。 -
双向数据绑定:
数据模型(Module)和视图(view)之间的双向绑定,视图改变,数据也会改变,数据改变,视图也会改变。
优点:
无需进行和单向数据绑定的那CRUD(Create,Retrieve,Update,Delete)
操作双向数据绑定最经常的应用场景就是表单了,这样当用户在前端页面完成输入后,不用任何操作,我们就已经拿到了用户的数据存放到数据模型中了。
promise可以解决回调地狱的底层原理是什么
回调地狱是因为异步回调函数嵌套太多。
Promise的内部也有一个 defers 队列存放事件,而 .then 方法的作用和发布订阅模式的on方法一样是用来订阅事件的,每次调用 .then 方法就会往defers队列中放入一个事件,当异步操作完成时, resolve方法标示前一个异步过程完成并从defers队列中取出第一个事件执行并返回当前对象保证链式调用,以此类推,就完成了所有异步过程的队列执行。
vue的生命周期
钩子函数 | 说明 |
---|---|
beforeCreate | vue实例创建(newVue())之后, 初始化完成, 创建之前调用, 无数据, 无模板, 未挂载 |
created | vue实例创建完成后调用, 有数据, 无模板, 未挂载 |
beforeMount | vue实例挂载前调用, 有数据, 有模板, 未挂载 |
mounted | vue实例挂载后调用, 有数据, 有模板, 已挂载 |
beforeUpdate | 数据更新前 |
updated | 数据更新后 |
activated | keep-alive 组件激活时调用 |
deactivated | keep-alive 组件停用时调用 |
beforeDestroy | 实例销毁前 |
destroyed | 实例销毁后 |
errorCaptured | 当捕获一个来自子孙组件的错误时被调用 |
深复制、浅复制
- 浅复制:
浅复制只会依次复制对象的每一个属性,不会对这些属性进行递归复制。
只是对复制对象的引用,栈和堆的关系,像number与string,boolean,null是栈的,直接可以用。 -
深复制:
深复制需要层层递归,复制对象的所有属性,包括对象属性的属性的属性...
1.for循环/遍历实现对象的深拷贝
2.转换成json再转换成对象实现对象的深拷贝
(json.parse(Json.strinify(arr))) -
总结:
object与Array存在占中,只用一个指针来引用值,拷贝之后的对象发生变化,原对象也会变化,只有真正的深拷贝才是真正的拷贝对象。
数组去重
1.for循环
2.es6 的set方法
var arr = [1,1,2,3,5,6,8,412,112,0,0,5];
//方法一
console.log(Array.from(new Set(arr)));
//方法二
console.log([...new Set(arr)]);
数组排序
冒泡排序
选择排序
sort排序
为什么axios在vue可以直接使用,而vuex要使用vue.use的使用场景
因为axios没有install,开发者在封装axios的时候,没有install这一步。
vue.use使用场景:vuex,vue-router,Mint-ui
install是默认的方法,当外界在use这个组件的时候就会调用本身的方法,同时传一个vue这个类的参数。
es6有哪些新特性?说说除了then跟catch,还用过哪些方法?
try..catch,try正确执行,catch错误执行。
es6特性:
1.const,let,用于定义变量
2.箭头函数,减少代码,函数
3.for ...of 遍历数组
4.class,类继承
5.解构,减少代码量
6.剩余展开符,得到剩余遍历
7.字符串模板,不用字符串拼接那么麻烦
acync await 等待一个异步方法执行完毕,放回结果。
清除浮动
1.clear:both
2.overflow:hidden
3.伪元素+zoom
http状态码
- 302:请求到的资源在一个不同的URL处临时保存 处理方式: 重定向到临时的URL
- 304: 请求的资源未更新 处理方式: 丢弃
- 404: 没有找到 处理方式: 丢弃
http的 8 种请求方式
请求方式 | 说明 |
---|---|
GET | 获取资源, 用来请求已被URI识别的资源 |
POST | 传输实体, 向服务器传输数据 |
HEAD | 获得报文首部, 用于确认URI的有效性及资源更新的日期时间等 |
PUT | 传输文件, 用来传输文件,就像FTP协议的文件上传一样,要求在请求报文的主体中包含文件内容,然后保存在请求URI指定的位置 |
DELETE | 删除文件, 服务器删除某个资源 |
OPTIONS | 询问支持的方法, 查询针对请求URI指定资源支持的方法 |
TRACE | 追踪路径, 让Web服务器端将之前的请求通信还给客户端的方法 |
CONNECT | 要求用隧道协议连接代理, 要求在与代理服务器通信时建立隧道,实现用隧道协议进行TCP通信 |
vuex有几个属性
Vuex有五个核心概念:state, getters, mutations, actions, modules。
- state:vuex的基本数据,用来存储变量
- getter:从基本数据(state)派生的数据,相当于state的计算属性
- mutation:提交更新数据的方法,必须是同步的(如果需要异步使用action)。每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。
回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数,提交载荷作为第二个参数。 - action:和mutation的功能大致相同,不同之处在于 ==》1. Action 提交的是 mutation,而不是直接变更状态。 2. Action 可以包含任意异步操作。
- modules:模块化vuex,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。
父子组件执行的顺序
- 加载渲染过程
父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted - 子组件更新过程
父beforeUpdate->子beforeUpdate->子updated->父updated - 父组件更新过程
父beforeUpdate->父updated - 销毁过程
父beforeDestroy->子beforeDestroy->子destroyed->父destroyed
你使用过的遍历方法 (哪些可以跳出循环)
for 和 for...in (使用break跳出循环)
Array.every() (使用return或者return false 跳出循环)
Array.some() (使用return true跳出循环)
forEach 和 Array.map (不能跳出循环)
$nextTick() $forceUpdate的用法
- $nextTick()
在Vue生命周期的created()钩子函数进行的DOM操作一定要放在Vue.$nextTick()的回调函数中
在created()钩子函数执行的时候DOM 其实并未进行任何渲染,而此时进行DOM操作无异于徒劳,所以此处一定要将DOM操作的js代码放进Vue.$nextTick()的回调函数中。与之对应的就是mounted()钩子函数,因为该钩子函数执行时所有的DOM挂载和渲染都已完成,此时在该钩子函数中进行任何DOM操作都不会有问题 。 - $forceUpdate
迫使Vue实例重新(rander)渲染虚拟DOM,注意并不是重新加载组件。结合vue的生命周期,调用$forceUpdate后只会触发beforeUpdate和updated这两个钩子函数,不会触发其他的钩子函数。它仅仅影响实例本身和插入插槽内容的子组件,而不是所有子组件;
应用场景: 当在data里没有显示的声明一个对象的属性,而是之后给该对象添加属性,这种情况vue是检测不到数据变化的,可以使用$forceUpdate()
了些什么
跨站脚本漏洞xss
https://www.jianshu.com/p/4fcb4b411a66
https://zhuanlan.zhihu.com/p/26177815
双向数据绑定原理
vue是采用数据劫持配合发布者-订阅者模式的方式,通过Object.definerProperty()来劫持各个属性的setter和getter,在数据变动时,发布消息给依赖收集器,去通知观察者,做出对应的回调函数,去更新视图。
mvvm作为绑定的入口,整合Observer,Compile和Watcher三者,通过Observer来监听model数据变化,通过Compile来解析编译模板指令,最终利用Watcher搭起Observer,Compile之间的通信桥梁,达到数据变化=>视图更新;视图交互变化=>数据model变更的双向绑定效果。
image.png
vuex的数据流向是怎么样的
1.用户触发行为actions 通过this.dispach(或者可以直接commit方法)
2.通过commit Mutations中的方法 改变state中 的值
3.最后通过this.$store.state.id的方法将值映射到页面上
vue-router的底层原理
vue-router通过hash与History interface两种方式实现前端路由,更新视图但不重新请求页面”是前端路由原理的核心之一,目前在浏览器环境中这一功能的实现主要有两种方式
1.hash ---- 利用URL中的hash(“#”)
2.利用History interface在 HTML5中新增的方法
在vue-router中,它提供mode参数来决定采用哪一种方式
- HashHistory
HashHistory真是身怀绝技,会很多东西。特别是替换路由特别厉害。还可以通过不同的方式,一个是 push ,一个是 replace . - HTML5History
History interface是浏览器历史记录栈提供的接口,通过back(), forward(), go()等方法,我们可以读取浏览器历史记录栈的信息,进行各种跳转操作。
从HTML5开始,History interface有进一步修炼:pushState(), replaceState() 这下不仅是读取了,还可以对浏览器历史记录栈进行修改
axios的底层原理
promise的底层原理
webpack原理
发布订阅模式和观察者模式
发送ajax请求,浏览器做了什么
vue里边对于数组的处理,有bug(数组修改了,页面没有修改?数组有十个数据,然后让它=0,会怎么样?)
- 数组修改了,页面没有修改
1.使用forceUpdate强制刷新
2.使用数组方法,例如push,splice等等
3.this.$set
https://www.cnblogs.com/zigood/p/11274692.html - 数组有十个数据,然后让它=0,会怎么样?
数组不会实时更新
vue里面有什么抽取公共方法的操作,或者说实现公共方法的技术
写成公共方法插件
created 里面有this吗?有dom吗?可以操作dom吗?
created里面有this,就是vue
没有dom,那个时候还没生成dom
可以操作dom,但是需要写在$nextTick()里边
mounted里面有一个方法,created里面有一个方法,现在有三个组件要执行这两个方法,有什么解决方案?
mixin
keep-alive原理
深复制有什么方法,有什么bug
1.Object.assign()方法。ES6提供了Object.assign()方法用于深拷贝。(有bug)
bug:只实现一层深拷贝,如果里边还有下一级对象,就不会被拷贝
2.Json.parse(Json.stringify(obj))方式
bug:只能处理简单的属性和简单的属性数组,构造器信息会丢失
3.for
注意:需要用hasOwnProperty去判断key是否存在,以防止对象中的某个key调用自己,导致无限循环
https://blog.csdn.net/yiyan12/article/details/79447202
对象继承的方式有哪些
1、原型链继承
2、借用构造函数继承
3、组合继承(1、2)
4、原型式继承
5、寄生式继承
6、寄生组合式继承