前端工程师面经--

1. js中8大数据类型,4大解决方案。

es5中6中属性类型:Undefined string boolean NAN,Number,Object
es6新增了一种:Symbol:这种对象永远不相等,解决属性名冲突的问题。
谷歌也出现了一种:bigInt,安全存储大整数
Object包含了(function Array,Data)
null和Undefined的区别:null只有一个值,是null,不存在的对象,表示一个空指针对象。undefined只有
一个值,是undefined没有初始化,派生于null
检测数组的方法:
1.typeof(操作符)
对于基本数据类型,除了null外,均可以正常返回,对于null返回object类型(在js种,null是一个空对象指针)
对于function,返回function类型
2.instanceof(用来判断A是否为B的实例,表达式为A instanceof B)
当A的__proto__指向B的prototype时,返回true
只能判断两个对象是否属于一个实例,而不能判断对象实例的具体数据类型。
3.constructor()
4.Object.prototype.toString()
toString()是object的原型方法,调用该方法,默认返回当前对象的[[class]],这是一个内部属性,格式为
[object xxx],其中xxx就是对象的类型
对于object对象,直接调用toString()就可以返回[object Object],而对于其他对象,需要通过call/apply
、调用才能返回正确的数据类型

2.axios和ajax区别:

区别:axios是通过promise实现对ajax技术的一种封装,救像JQuery封装ajax一样,简单来说,ajax技术实现了网页的局部刷新,
axios实现了对ajax的封装。
axios({ 1.用于浏览器和node环境下的http请求,基于promise同步。
url:’/user/xxx’, 2.可以自动将数据转换为json格式。
method:‘POST’ 3.支持防止CSRF(跨站请求伪造)
responseType:‘json’, 4.拦截请求和响应
data:{
a:a,
b:b
}
}).then(res=>{
}).catch(error=>{
})
ajax({ 1.jquery的ajax,适用于原来的MVC模式,对于现在的MVVM模式已经不再适用,是基于异步js和
url:‘xxx’, xml 核心是XMLHttpRequest();
type:‘GET’, 2.获取ajax对象,接受并且返回
dataType:‘json’, xhr.onreadystatechange=function(){
data:{ if(this.readystatus4){
a:1,b:2 console.log(4) readystatus
4代表接受到返回
}, }
success(res){}, }
error(res){}
})

3.Ajax是什么?

·····Ajax并不算是一种新技术,全称是asynchronous javascript and xml,可以说是已有的技术的组合,
主要是用来实现客户端和服务器端的异步通信的效果,实现页面的局部刷新,早期的浏览器不支持原生
的Ajax,使用隐藏帧iframe方式变相实现一部效果。
·····使用Ajax原生方式发送请求主要通过XMLHttpRequest(标准浏览器),ActiveXobject(IE浏览器),
对象实现异步通信的效果
·······基本步骤
var xhr=null;//创建对象
if(window.XMLHttpRequest){
xhr=new XMLHttpRequest();
}else{
xhr=new ActiveXobject();
}
xhr.open(“方式”,"地址”,“标志位”) //初始化请求 open(“get”,“1.html”,true);//调用open方法并且采用异步方式
xhr.setRequestHeader(“Content-type”,“application/x-www-form-urlencoded || application/json”)//设置http请求头信息
xhr.onreadystatechange=function(){};//指定回调函数
xhr.send()//发送请求。
2.AJax的使用以及实现步骤
(1)创建XMLHttpRequest对象,也就是创建一个异步调用对象。
(2)创建一个新的HTTP请求,并指定该HTTP请求的方法,URL以及验证信息。
(3)设置相应的http请求状态变化的函数。
(4)发送http请求
(5)获取异步调用返回的数据
(6)使用js和dom局部实现刷新
(1).var xhr=null;
if(window.XMLHttpRequest){
xhr=new XMLHttpRequest();
}else {
xhr=new ActiveXobject();
}
(2)创建一个新的http请求
xhr.open(methods,url,async);
(3)创建一个http请求头信息
xhr.setRequestHeader(“content-type”,“application/json/x-www-form-urlencoded”);
(4)发送请求
xhr.send();
(5)获取异步回调返回的数据
xhr.onreadyStatechange=function(){
if(xhr.readyState=4&&&xhr.status=200){
}
}

4.apply call bind的相同点 都是用来改变this的指向

(1).call()和apply的区别:
相同点:都是调用一个对象的一个方法,用另一个对象替换当前对象。
不同点:参数书写的方式不同
call()第一个参数是this指向的对象,第二个传入参数列表,当第一个参数传入null undefined时候,默认指向window
apply():第一个参数是this要指向的对象,第二个参数是数组
例如:B.call(A,args1,args2) B.apply(A,arguments)

(2)call()和bind()的区别
相同点:都是用来改变this指向的
不同点:call()改过this的指向后,会再执行函数,bind改过this指向之后,不执行函数,会返回一个绑定新的
this的函数

5.axios请求

好处:
1.支持浏览器和nodejs
2.支持promise
3.能拦截请求和响应
4.自动转换数据为JSON格式
常用API
get:查询数据
post:添加数据
put:修改数据
delete:删除数据

axios默认地址的配置
axios.defaults.baseURL=‘http://localhost:3000/app’
通过axios请求拦截器添加了token
axios.intercepter.request.use(config=>{
config.headers.Authoriazation=window.sessionStorage.getItem(’‘token’)
return config;
})

6.box-sizing的属性有哪些?

content-box:标准盒模型,也成为W3C盒模型,盒子定义的width和height不包含padding和border,
盒子的实际宽度=定义的width+padding+border+margin、
border-box:怪异盒模型,IE盒模型,盒子定义的width包含了padding和border
盒子的实际宽度=定义的width+margin
inherit:规定从父元素继承box-sizing 属性的值

7.CSS3新增特性:

(1).新增的选择器:属性选择器,结构伪类选择器,伪元素选择
(2).CSS3新增的transform rotate(旋转) scale(缩放) translate(移动)
(3).CSS3新增的动画功能:transition(平滑过渡) animation(关键帧)keyframes
(4).CSS新增的边框样式":border-radius(圆角边框) border-image(图片边框)
(5).CSS3盒模型相关的属性:box-shodow(盒阴影)text-shadow(文本阴影) box-sizing盒模型
(6). 渐变色(gradient)
(7).布局: 多栏布局 flex弹性盒子布局
(8).背景:background-clip(背景裁剪), background-size(图片大小 cover/contain)
background-origin(属性相对什么位置来定位)

8.CSS选择器以及优先级:

1.标签选择器
2.class属性选择器
3.ID选择器
4.组合类型选择器(后代选择器,群组选择器)
5.选择器的优先级顺序
A B C D
A:内联样式
B:ID选择器
C:类选择器 和 属性选择器 和伪类选择器
D:标签选择器 和 伪元素选择器

!important>内联>ID选择器>class选择器>标签选择器

9.ES6新增的特性:

(1)let const
其中let声明变量和const声明常量,两者都有块级作用域。ES5中var是没有块级作用域的,并且存在变量提升。
(2)箭头函数
ES6中使用箭头函数来定义。使用箭头函数之后,this就不是指向window,而是指向父级。不能够使用
arguments对象。不能用作构造函数,不可以使用yield命令。
(3)模板字符串(``)
模板字符串是增强版的字符串,用反引号标识,可以当普通字符串使用,也可以定义多行字符串。
(4)解构赋值
ES6按照一点过的模式,从数组和对象中提取值。
(5)for…of循环
可以遍历数组,Set,Map结构,某些类似数组的对象,对象,以及字符串。
(6)import export导入导出
(7)Set数据结构
类似数组,所有数据都是唯一的,没有重复的值。本身是一个构造函数。
(8)…展开运算符
可以将数组和对象里面的值展开,还可以将多个值收集为一个变量。
(9)class类继承
(10)async await
搭配promise,可以编写出来形似同步的代码来处理异步的流程,提高代码的简洁性和可读性。
(11)promise
异步编程的解决方案。

10.get和post请求的区别

了解历史:首先get和post是HTTP请求与服务器交互的方式,说到方式,其中总共有四种:get,post,put,delete
所以get是获取数据,post是修改数据。
2.区别:
(1)get是把请求的数据放在url上,既http协议头上,其格式为:以?分割的URL和传输数据,参数之间以&分割。
post是把数据放在HTTP请求包体内。
(2)get提交的数据最大是2k(原则上url长度无限制,但是限制取决于浏览器,大多数浏览器支持64k),post无限制
(3)get产生一个一个TCP数据包,浏览器会把http Header和data一并发送出去,服务器响应200(返回数据)
post产生2个TCP数据包,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok;
(4)get请求浏览器主动缓存(主动保存参数),post不会

11.HTML5新特性:

(1).input type表单的新特性 email number time url search
(2).用于媒介回放的audio和video
(3).用于绘画的canvas元素
(4).本地存储localStorage和sessionStorage
(5).新的特殊内容标签:header footer article section nav aside

12.http和https的区别?

HTTP:超文本传输协议,是互联网上应用最为广泛的一种网络协议。设计HTTP最初的目的是为了提供一种发布和接受HTML的
方法。HTTP协议是以明文方式发送信息的,如果黑客截取了Web浏览器和服务器之间的传输报文,就可以直接获得其中的信息。
HTTPS:是以安全为目标的HTTP通道,是HTTP的安全版。HTTPs的安全基础是SSL,SSL协议位于TCP/IP协议与各种应用层协议
之间,为数据通讯系统安全支持。SSL协议分为两层,SSL记录协议,它建立在可靠的传输协议之上,为高层协议提供数据封装。
SSL握手协议,建立在SSK协议记录之上,用于数据传输前通讯双方进行身份认证,协商加密算法,交换加密密钥等。
两者的区别:
1.HTTP是超文本传输协议,信息是明文传输,HTTPS则是具有安全性的SSL加密传输协议。
2.HTTP和HTTPS使用的是完全不同的连接方式,使用的端口也不一样,前者是80,后者是443
3.HTTP的连接是简单的,是无状态的。HTTPs协议是由SSL+HTTP协议构建的可进行加密传输,身份认证的网络协议,比HTTP
协议更安全。(无状态的意思是其数据包的发送,传输和接受都是相互独立的)
4.HTTPS协议需要到CA申请证书,一般免费的较少,需要一定的费用。

13.状态码:

2xx:表示请求成功
200表示正常返回信息 201表示服务器请求成功并且服务器创建了新的资源 202服务器接受请求但未处理

3xx:重定向
303表示临时重定向,且总是使用GET请求新的URL

4xx:通常是请求错误 格式错误 请求未授权 请求地址错误
400 请求无效 格式错误 401请求未授权
404请求地址错误,服务端找不到

5xx:通常是服务器端的错误
500最常见的服务器端错误。

14.js数组遍历方法

1.使用for循环 while循环 do while循环
2.forEach():为每个数组元素调用一次(回调函数),无返回值。
3.map():通过对每个数组元素执行函数,返回一个新数组。
4.filter():过滤出数组中符合条件的元素,返回一个新数组。
5.every():用于检测数组中所有元素是否都符合指定条件(都要满足),返回布尔值。
6.some():用于检测数组中的元素是否满足指定条件(只要有一个满足条件),返回布尔值。
7.find():返回符合数组的第一个元素的值。
8.findIndex():返回符合条件的数组的第一个元素的位置。
9.reduce():方法对数组中的每一个元素执行由你提供的reducer函数(升序执行),将结果汇总为单个
返回值。
10.for in循环 :其实是对象遍历的方式,而不是数组专有,一般不推荐使用(他通常表现出有序,因为
他是按照对象的枚举顺序来遍历的,也就是规范没有规定顺序的。)
11.for of循环 :这个方法用于可迭代对象的遍历,用来遍历数组是有序的,并且迭代的是数组的值。

15.js数组的方法:

(1).join():将数组的元素组成一个字符串。
(2).push()和pop()
push():添加一个元素到数组的末尾,并且返回修改后的数组长度。
pop():删除一个数组末尾的元素,并且返回删除的项。
(3).shift()和unshift()
shift():删除原数组的第一项,并返回删除元素的值。
unshift():将参数添加到数组的开头,并返回数组的长度。
(4).sort()
sort():按照升序排列数组项。返回排序后的数组,原数组未发生改变。
(5).reverse()
reverse():翻转数组项的顺序。原数组发生了改变
(6).concat()
concat():连接两个或者多个数组,然后返回一个新数组。原数组未发生改变。
(7).slice()
slice():返回从原数组中指定开始下标到结束下标之间的项组成的新数组。接受两个参数,数组下标;
原数组不发生改变。
(8).splice()
splice():很强大的数组方法,可以实现删除,插入,和替换
删除:可以删除任意数量,两个参数:要删除第一项的位置和删除的项数。
插入:向指定位置插入任意数量的项,三个参数:起始位置,0(要删除的项数),要插入的项数
替换:向指定的位置插入任意数量的项,且同时删除任意数量的项,例如splice(2,1,4,6)删除位置2的项,从2
开始插入4,6两项。
splice()方法返回一个数组,该数组包含被删除的项。
(9).indexOf()和lastIndexOf()
indexOf():接受两个参数:要查找的项和表示查找起点位置的索引(可选的)。从数组开头查找。
lastIndexOf():接受两个参数:要查找的项和表示查找七点的索引(可选的)。从末尾查找
没找到的情况下返回-1

16.keep-alive和restful

(1).keep-alive:用来缓存组件,避免多次加载相应的组件,减少性能的消耗。从页面1->页面2,再返回页面1,
只会从缓存中加载之前已经缓存的页面1.
(2).一句话概括restful:URL定位资源,用http描述操作()

17.MVVM实现原理

1.首先我们来谈谈什么是MVC
MVC是Model-View-Controller的缩写 既模型----视图------控制器
Model------后端传递的数据
View--------所看到的视图页面
Controller-------页面的业务逻辑。
MVC是单向通信,必须通过Controller来承上启下。 使用MVC的目的就是将M和V的代码分离。
MVC和MVVM的区别就是:MVVM并不是VM完全取代Controller,ViewModel存在的目的在于
抽离Controller中展示的业务逻辑,而不是替代Controller,其他视图操作业务还是放在Controller
中实现,也就是说MVVM实现的是业务逻辑组件的重用。
2.再MVVM是什么
MVVM是Model------View----ViewModel 既模型-----视图-----视图模型
Model-------后端传递的数据
View---------所看到的页面
ViewModel----------MVVM模式的核心,它是链接Model和View的桥梁。
ViewModel有两个方向:
·····将Model转化成View,既将后端传递的数据转化成所看到的页面,实现的方式是:数据绑定;
·····将View转化成Model,既将所看到的页面转换成后端的数据。实现的方式是:DOM事件监听。
这两个方向都是实现的,我们称之为数据的双向绑定。
总结:在MVVM的框架下,视图和模型是不能直接通信的,他们是通过ViewModel来通信。
ViewModel通常要实现一个Observer观察者,当数据发生变化,ViewModel能够监听到数据的
这种变化,然后通知到对应的视图做自动更新,而当用户操作视图,ViewModel也能监听到视图
的变化,然后通知数据做改动,这实际上就实现了数据的双向绑定。

18.promise是什么?

1.两种类型的回调函数
同步回调:立即执行,完全执行之后结束,不会放到回调队列中去。/数据遍历
异步回调:不会立即执行,会放入到回调队列中将来执行 /定时器/promise的成功失败回调/
2.promse是什么:promise是js中执行异步操作的新的解决方案
从语法上来说:promise是一个构造函数
从功能上来说:promise对象用来封装一个异步操作并且可以获取其结果。
promise状态改变:
pending-resolved(fulfilled已完成 ) pending-rejected 只有这两种,并且promise对象的状态只能改变一次,无论改变
成功还是改变失败,都会有一个结果数据。
4.为什么使用promise
promise支持链式调用,解决回调地狱的方法。指定回调函数的方式更加灵活

19.谈一谈em和rem的区别?

(1)rem是css3新增的一个相对单位,相对于根元素(即html元素)font-size计算值的倍数。
简单来说就是一个相对单位。
作用:利用rem可以实现简单的响应式布局,可以利用html元素中的字体大小和屏幕间的比值
设置font-size的值,实现当屏幕分辨率变化的时候元素的rem值也变化。rem配合媒体查询
(@media screen and {min-width:320px}) rem=屏幕宽度/font-size
(2)em是文本相对长度单位,em是指相对父元素的字体大小的单位。他和rem比较相似,默认px

20.vue-router路由:

vuejs官方的路由管理器
1.包含的功能:
支持嵌套路由
支持编程式路由
支持命名路由
支持路由参数
2.基本使用
···引入相关库文件
···添加路由链接User router-link被渲染成a标签 to
渲染成href标签
···添加路由填充位 router-view
···定义路由组件
···配置路由规则并且创建路由实例
var router=new VueRouter({
routes:[
{path:’/user’,component:User},
{path:’/register’,component:Register}
]
})
每个路由规则至少包含path和component
path表示当前路由规则匹配的hash地址
component表示当前路由规则对应的组件
···挂载路由到vue实例中

路由重定向:redirect属性 指定一个新的路由地址 表示要被重定向的新地址
嵌套路由用法:父级通过children属性匹配子级路由。
路由传参:props
路由编程式导航:(1)声明式导航:点击链接来实现导航的方式
(2)编程式导航:通过js的形式的api实现导航的方式。this.$router.push(‘hash地址’)

21。sessionStorage localStorage和cookie区别

1.cookie是网站为了标识用户的身份存储在用户本地终端上的数据。
cookie数据在每次同源http请求中都会携带,既在浏览器和服务器之前来回传递。
2.sessionStorage和localStorage不会把数据自动发给服务器,而是在本地存储。
区别:
存储大小 cookie 4kb
sessionStorage localStorage虽然也有存储限制,但是比cookie大得多,可以达到5MB或者更大。
过期时间:
localStorage:存储持久的数据,浏览器关闭之后不会丢失数据,除非主动删除数据。
sessionStorage:数据在浏览器窗口关闭之后自动删除。
cookie:设置的cookie过期时间之前一直有效,即使窗口关闭或者浏览器关闭。

22.Set和Map区别和用法

Set
ES6中提供了新的数据类型Set,它类似于数组,但是成员的值都是唯一的,没有重复的值。Set本身还是一个构造函数,用来
生成Set数据结构。
Set实例有一下属性: Set.prototype.size返回Set实例的成员总数。
Set实例的四个操作方法:
······add(value)添加某个值,返回Set结构本身。
······delete(value)删除某个值,返回一个布尔值,表示删除是否成功。
······has(value)返回一个布尔值,表示该值是否为Set的成员
······clear():清除所有成员,没有返回值
Set遍历:
forEach():使用回调函数遍历每个成员
keys():返回键名的遍历器
values():返回键值的遍历器
entries():返回键值对的遍历器
2.Map
JavaScript的对象(Object),本质上是键值对的集合(Hash),但是传统上只能用字符串当作键,给他的使用带来了限制。
为了解决这个问题,ES6提供了Map数据结构,它类似于对象,也是键值对的集合,但是键的范围不在局限于字符串,各种
类型的值(包括对象)都可以当作键。Object提供了“字符串-值”,Map结构提供了”值-值“的对应,完善的Hash结构实现。
Map遍历:
forEach():使用回调函数遍历每个成员
keys():返回键名的遍历器
values():返回键值的遍历器
entries():返回键值对的遍历器
Map实例的操作方法:
get(key):get读取key对应的键值,如果找不到key,返回undefined。
delete(value)删除某个值,返回一个布尔值,表示删除是否成功。
has(value)返回一个布尔值,表示该值是否为Map的成员
clear():清除所有成员,没有返回值

23.Vuex管理状态的机制;

1.vue是什么?Vuex是一个专为vue。js应用程序开发的状态管理的vue插件。
2.作用:集中式管理vue多个组件共享的状态和从后台获取的数据。
(1).state:提供为一个公共数据源,所有共享的数据同意放到store中的state
{this.KaTeX parse error: Expected 'EOF', got '}' at position 19: …re.state.全局数据名称}̲ (2).mutation用于…store.commit(’’) import {mapMutation} from vuex}
(3)action用于处理异步任务,但是在action中,不能直接修改state中的数据,必须
通过mutation来间接变更state;
this. s t o r e . d i s p a t c h ( 4 ) . g e t t e r 用 于 对 s t o r e 中 的 数 据 加 工 处 理 形 成 新 的 数 据 , 类 似 于 v u e 中 的 计 算 属 性 t h i s . store.dispatch (4).getter用于对store中的数据加工处理形成新的数据,类似于vue中的计算属性 this. store.dispatch(4).getterstorevuethis.store.getters.名称

24.vue的两大核心

数据驱动
组件系统
(1)数据驱动----也就是数据的双向绑定。
数据的双向绑定原理:vue采用数据劫持结合发布者-订阅者模式的方式,通过object.defineProperty()
来劫持各个属性的setter和getter,在数据变动时发送消息给订阅者,触发相应的监听回调。
(2)组件系统-----模板 初始化数据 接受props参数 方法methods 生命周期钩子函数 私有资源(
自定义指令,过滤器,组件)。

25.什么是vue的生命周期?

这么说吧:vue实例从创建到销毁的过程,就是vue的声明周期。也就是从开始创建,初始化数据
编译模板,挂在DOM-渲染,更新渲染,卸载等等一系列的过程,我们称之为生命周期。
那么,vue的生命周期的作用是什么?
vue所有的功能实现都是围绕其声明周期进行的,在命周期的不同阶段调用对应的钩子函数可以实现
组件数据管理和DOM渲染两个重要功能,生命周期有许多钩子函数,能够在整个vue项目中形成更好的
逻辑。
beforeCreate 创建前 此阶段为实例初始化之后,this指向创建的实例,此时的数据观察事件机制都未
形成,不能获得DOM节点。data,computed,watch,methods上的方法和数据均不能访问。可以在这
加个loding事件
created 创建后,此阶段为实例已经创建,完成了数据data的初始化,可访问data,computed,watch,
methods上的方法。但是未挂载DOM; 初始化完成时的事件和异步请求都可以写在这里,不宜过多,避免
白屏事件长。
beforeMounted挂载前,虽然得不到具体的DOM元素,但是VUE挂载的根节点已经创建,下面的vue操作
也对DOM的操作将围绕这个根元素继续进行。 这个阶段时过渡性的,一般一个项目只使用一两次
Mounted 挂载,完成创建DOM挂载和数据双向绑定。可以在钩子函数中对挂载的DOM进行操作。
可以在这个阶段发起后端请求,拿回数据,配合路由钩子做一些事情。
beforeUpdate和Updated 数据更新前 ,驱动DOM,数据更新后虽然没有立即更新数据,但是DOM中
的数据会改变,这是vue双向绑定的作用。数据更新后,完成虚拟DOM的重新渲染和打补丁。
beforeDestroy和destroyed 销毁前,可做一些删除提示。销毁后,当前组件已经被删除,销毁监听事件,
组件,事件,子实例也被销毁。

26.谈谈vue中v-for关键子key的作用原理

首先 了解一下diff算法的处理方法
对操作前后的DOM树同一层的节点进行对比,一层一层对比。
当某一层有很多相同的节点时,也就是列表节点,Diff算法的更新过程默认情况下遵循上面原则,相当没有
效率。
所有我们需要key、来给每一个节点做一个唯一的标识,Diff算法就可以正确的识别此节点,找到正确的位置
区插入新的节点。

v-for中key关键子的作用是什么?
key的作用主要就是为了更高效的更新虚拟DOM,使用key值,他会基于key的变化重新排列元素顺序,
并且会移除key不存在的元素。
为什么不推荐使用index作为key值?
当以数组下标作为key值的时候,其中一个元素(增删改查)发生变化可能会导致所有元素的key值发生了变化。

27.vue中监听器和计算属性的区别

methods:不存在缓存,执行一次运行一次。执行n次,运行n次。
computed:计算属性。
使用场景:当页面中有些数据依赖其他数据进行变动的时候,可以使用计算属性,计算属性时基于data中数据
进行处理的,data数据变化,他也跟着变化,当data中数据没有变化,调用computed函数n次,只会进行
缓存(执行一次)。
watch:侦听器
类似于监听机制+事件机制。
如果在数据变化的同时会进行异步操作或者时比较大的开销,那么一般使用watch。当数据发生变化的时候,,
侦听器侦听到数据变化,会立刻监听

28.vue之间传值

1.父组件向子组件传值
props来接收父组件传递过来的值
2.子组件向父组件传值
通过自定义事件的方式: e m i t ( ) 3. 兄 弟 组 件 相 互 调 用 属 性 或 者 方 法 单 独 的 事 件 管 理 中 心 e v e n t B u s 监 听 事 件 e v e n t B u s . emit() 3.兄弟组件相互调用属性或者方法 单独的事件管理中心eventBus 监听事件 eventBus. emit()3.eventBuseventBus.on()
触发事件 eventBus. e m i t ( ) 4. V u e x 共 享 数 据 组 件 全 局 状 态 管 理 机 制 5. 利 用 r e f 属 性 获 取 子 组 件 的 属 性 或 者 方 法 利 用 emit() 4.Vuex共享数据组件全局状态管理机制 5.利用ref属性获取子组件的属性或者方法 利用 emit()4.Vuex5.refparent属性获取父组件对象,从而调用父组件的属性方法

29.从url请求到显示页面,都经历了什么?

一般会经历以下几个过程:
1.首先,在浏览器地址中输入url
2.浏览器先查看浏览器缓存–系统缓存—路由器缓存,如果缓存中有,会直接在屏中显示页面内容,或没有,跳转到第三步。
3.在发送http请求前,需要域名解析(DNS解析)(DNS(域名系统,Domain Name System)是互联网的一项核心服务,
它作为可以将域名和IP地址相互映射的一个分布式数据库,能够使人更方便的访问互联网,而不去记住ip地址),解析获取相
应的IP地址。
4.浏览器向服务器发起TCP连接,与浏览器建立tcp三次握手。(TCP既传输控制协议。TCP连接是互联网连接协议集的一种)
5.握手成功后,浏览器向服务器发送http请求,请求数据包。
6.服务器处理收到的请求,将数据返回至浏览器。
7.浏览器收到了HTTP响应。
8.读取页面内容,浏览器渲染,解析html源码。
9.生成DOM树,解析CSS样式,js交互。
10.客户端和服务器端交互。
11.ajax查询

30.js反转字符串

方式1
这种方式比较简单推荐使用
split()字符串转数组 reverse()数组翻转元素位置方法 join()数组转字符串
既 str.split(’’).reverse().join(’’)

方法2
定义一个新的字符串,遍历str,charAt()是取字符串的一个字符,先去最后一个字符
再取倒数第二个,依次类推
let str=“Hello world”
let newStr="";
for(let i=0; i let s=str.charAt(str.length-i-1);
newStr+=s;
}

31.箭头函数和普通函数的区别:

(1).首先谈一谈箭头函数的this指向
1.箭头函数由于没有prototype(原型),所以箭头函数本身没有this。
2.箭头函数的this指向在定义的时候继承自外层第一个普通函数的this。被继承的普通函数的this指向如果
发生了改变,箭头函数的this会跟着改变。
3.不能直接修改箭头函数的this指向。通过修改继承的普通函数的this,来改变箭头函数的this指向/
4.箭头函数外层如果没有普通函数,则他的this指向window
(2).语法上的差异
1.单条处理可以省略return和大括号 单个参数可以省略小括号
2.箭头函数不能作为构造函数,不能使用new
3.箭头函数不绑定arguments,但是可以使用…rest参数。

32.跨域的解决方案

同源策略:同源指的是协议、域名、端口号、皆相同。
使用同源策略的原因:出于安全考虑,主要是为了防止CSRF攻击
跨域:跨域主要是用于突破同源策略的
跨域的几种解决方式:
1.JSONP
原理:利用

33.练习防抖

//函数防抖:指的是响应函数在一段时间后才执行,如果中间再次触发事件,则重新计算响应时间
function debouce(func,wait){
let timeout;
return function(){
let _this=this;
let args=arguments;
clearTimeout(timeout);
timeout=setTimeout(()=>{
timeout=null;
func.apply(_this,args);
},wait)
}
}
应用:搜索框输入查询,表达验证,按钮提交时间,scroll事件的滚动触发

34.练习节流

//函数节流:指的是函数在一段时间内只执行一次,如果在这段时间内连续触发多次,只执行第一次,忽略其他的点击
应用:按钮在一段时间内重复点击提交表单
射击游戏每隔一段时间射击
计算鼠标移动的距离
//时间戳实现
function throttle(func,wait){
let _this,args;
let old=0;
return function(){
_this=this;
args=arguments;
let now=new Date().valueOf();
if(now-old>wait){
func.apply(_this,args);
old=now;
}
}
}
//2.定时器实现
function throttle(func,wait){
let _this,args;
let timeout;
return function(){
_this=this;
args=arguments;
if(!timeout){
timeout=setTimeout(()=>{
timeout=null;
func.apply(_this,args);
},wait)
}
}

35.冒泡排序和快速排序

冒泡排序:每次比较相邻的两个数,如果前一个数小于后面的,换位置
function bubbleSort(arr) {
for (var i = 0; i < arr.length; i++) {
for (var j = 0; j < arr.length - i - 1; j++) {
if (arr[j + 1] < arr[j]) {
swap(arr[j + 1], arr[j]);
}
}
}
return arr;
}
// 快速排序:采用二分法,去除中间数,数组每次和中间数比较,小的放在左边,大的放在右边
function quickSort(arr) {
if (arr.length == .0) {
return [];
}

var cIndex = Math.floor(arr.length / 2); //找基准
var c = arr.splice(cIndex, 1); //找到这个基准元素并且删除
var left = [];
var right = []; //定义左右数组
//比基准小的放在left   比基准大的放在right
for (var i = 0; i < arr.length; i++) {
    if (arr[i] < c) {
        left.push(arr[i]);
    } else {
        right.push(arr[i]);
    }
}
return quickSort(left).concat(c, quickSort(right));

}

36.前端如何优化网站性能:?

(1).减少HTTP请求数量
1.CSS Sprites:俗称精灵图,这个技术将多个图片合并成一张图片,达到减少HTTP请求的一种方法。
2.LazyLoad图片懒加载:可以控制页面内容在一开始无需加载,不需要发送请求,等到用户真正需要的时候,
立即加载出内容。
3.合并CSS和JS文件:现在前端有很多工程化打包工具,如:webpack,gulp。为了减少HTTP请求数量,
可以通过这些工具再发布前将多个CSS或者多个JS合并成一个文件。
(2).控制资源文件加载优先级
浏览器在加载HTML内容时,是将HTML内容从上至下依次解析,解析到link或者script标签就会加载href或者
src对应链接内容,为了第一时间展示页面给用户,就需要将CSS提前加载,不要受JS加载的影响。一般CSS在
头部,JS在底部。
(3).利用浏览器缓存
浏览器缓存指的是将网络资源保存在本地,等待下次请求该资源时,如果资源已经存在,就不需要到服务器
重新请求该资源,直接在本地读取该资源。
(4).尽量减少对DOM的操作
(5).图标使用IconFont替换
(6).减少重排reflow
基本原理:重排DOM的变化影响到元素的几何属性,浏览器会重新计算元素的几何属性,会时渲染树中
受到影响的部分失效。减少重排,如果需要在DOM操作时添加样式,尽量使用增加class属性,而不是通过
style操作样式。

37.清除浮动的方法:

(1)给父元素添加伪类(最推荐的方法)
.clearfix:after{
content:’’,
display:block;
height:0,
clear:both,
visibility:hidden
}
.clearfix{
zoom:1;
}
(2)给父元素添加overflow:hidden(内容增多的时候没办法显示溢出的元素)
(3)在浮动元素的后面添加空标签(W3C推荐的,但是会有多余的标签 不推荐使用)
(4)给浮动的元素的父辈容器添加高度。
(5)使用清除浮动属性 clear:both(浮动的父辈元素仍然没有高度)

38.什么是事件代理?

//首先了解什么是DOM事件流
DOM事件流分为三个阶段:事件捕获,目标阶段,事件冒泡
1.事件捕获阶段:由目标节点的祖先节点逐级传播道目标节点。由文档的根节点开始触发对象,最后传播
到目标节点,从外向内捕获事件对象。
2.目标阶段:事件到达目标对象,事件触发,如果事件不允许触发冒泡,事件会在这一阶段停止传播。
3.冒泡阶段:从目标节点逐级传播道document节点。
target。addEventListener(type,listner[,useCapture])
type:事件名称,大小写敏感
listener:监听函数。事件发生时,会调用该监听函数。
useCapture:布尔值,true(事件捕获阶段触发),默认false(事件冒泡阶段触发)

阻止事件冒泡:event.stopPropagation()
阻止默认行为:event.preventDefault()

事件委托是什么?
由于事件会在冒泡阶段向上传播到父节点,因此可以把子节点的监听函数定义在父节点上,由于父节点的监听
函数统一处理多个子元素的事件。(减少内存消耗,提高性能 比如100button 只需要绑定一个事件)
(动态绑定事件,由于新创建的节点没办法绑定,就需要借用事件代理)

39.数组的检测方法

1.不能够使用typeof判断是否属于数组 因为返回object
2.instanceof用于判断某个构造函数的prototype属性所指向的对象是否存在于另一个要检测对象的原型链上。
(判断某个实例是否属于某个对象)
var a=[1,2,3,4]
a instanceof Array 输出true
3.Object.prototype.toString()
如果一个对象的toString()没有被重写的话,那么toString()将会返回[Object xxx],其中xxx就是对象的类型
对于Object对象,可以直接调用toString() 对于其他对象,需要调用call/apply才能返回正确数据类型
4.Array.isArray()用于确定传递的值是否是一个Array

40.数组去重

数组去重有非常多的方法 这里简单介绍两种常用的数组去重方法
方法一:利用ES6 Set去重(Set数据结构类似于Map数据结构,没有重复的key)
function Unique(arr){
return Array.from(new Set(arr)); //Array.from()方法转数组
}
方法二:利用indexOf()方法进行数组去重
function unique(arr){
if(!Array.isArray(arr)){
console.log(‘type error’);
return;
}
var result=[];//结果数组
for(var i=0;i //如果在结果数组中没有发现arr[i],那么就把arr[i]放入到result中去
if(result.indexOf(arr[i])===-1)
result.push(arr[i]);
}
return result;
}
方法三:利用sort()
function unique(arr){
if(!Array.isArray(arr)){
console.log(‘type error’);
return;
}
arr=arr.sort();//先排序
var result=[arr[0]];//创建结果数组
for(var i=1;i if(arr[i]!===arr[i-1]){
result.push(arr[i]);
}
}
}

41.谈谈this指向。

首先要说的是,this的指向在函数定义的时候是确定不了的,只有当函数执行的时候,才知道this
到底指向谁,实际上this最终的指向是那个调用他的对象。
下面就简单介绍一下常见情况下this的指向。
(1).普通函数this的指向
普通函数如果直接被调用,则this指向全局对象window
(2).构造函数中的this
构造函数中的this始终指向构造出来的实例。
使用new来调用函数
1.创建一个全新的对象
2.新对象会被执行prototype
3.新对象会被绑定到函数调用dethis
4.如果函数没有返回其他对象,new表达式中的函数表达式会返回这个新对象
(3).对象方法中的this
对象方法调用的时候,此时this指向该方法所属的对象。
(4).事件绑定中的this
指向的是绑定事件的对象,就是this指向button
(5).定时器中的this
指向window
(6).箭头函数中的this
首先 箭头函数中是没有this 的 箭头函数中的this继承至箭头函数外部环境中普通函数的
this指向。

改变this指向的方法:
call apply bind

42.谈谈vue中虚拟dom是什么?

是什么虚拟DOM?
官网给出的概念:Vue通过建立一个虚拟DOM树对真实DOM发生的变化保持追踪。

一颗真实的DOM树的渲染需要先解析CSS样式和DOM树,然后将其整合成一颗渲染树,再通过
布局算法去计算每个接电脑再浏览器中的位置,最终输出到显示屏上。
而虚拟DOM则可以理解为保存了一颗DOM树被渲染之前所包含的所有信息,这些信息通过对象的形式、
保存在内存中,并通过js的操作进行维护。

例如:

  • 1
  • 2
  • 3

要删除1 在3的后面插入4
传统的DOM操作:需要先删除1,在插入4 ,这个操作包含了两个js和DOM之间的交互操作,性能欠缺。
虚拟DOm就是为了减少这种交互而设计的。
第一步:通过树的形式保存旧的DOM信息,检测到数据更新之后,需要更新DOM,现在js中将需要修改的
节点信息全部修改,将最终生成的虚拟DOM树更新到视图中去,这个过程中,只进行了一次Dom树的交互。

43.谈谈闭包

是什么是闭包?
首先,我们如果想要理解闭包就必须先了解变量的作用域,在JS中存在两种变量的作用域,一种
是全局变量,另一种是局部变量。两种变量的区别就是函数内部可以直接读取全局变量,但是在
函数的外部没有办法读取函数内部的局部变量。

这个时候,闭包的出现。
闭包是指有权访问另一个函数作用域中局部变量的函数,声明在一个函数中的函数,叫做闭包函数,
而且内部的函数总是可以访问外部函数中声明的局部变量。

闭包的特点:
1.让外部访问函数内部变量成为可能
2.局部变量会常驻内存 会造成内存泄漏(有一块内存空间被长期占用,而不被释放)
3.可以避免使用全局变量,防止全局变量污染。

## 44.常见的行内元素 常见的块级元素 常见的空元素
行内元素:input select button
块级元素 :


      空元素:

      45.js有那些内置对象?

      数据封装类对象:Object Array Boolean Number String
      其他对象:Function Arguments Math Date Error

      46.eval是做什么的?

      他的功能是把对应的字符串解析成JS代码并运行。应该避免使用eval 不安全 耗能

      47.DOM怎么添加,移除,移动,复制,创建和查找节点。

      //创建新节点
      creatElement 创建一个具体的元素
      creatTextNode 创建一个文本节点
      createDocumentFragment 创建一个DOM片段
      //添加移除替换插图
      appenChild()
      removeChild()
      replaceChild()
      insertBefore()
      //查找
      getElementsByTagName()//通过标签名查找
      getElementsByName() //通过元素的Name属性查找
      getElementById() //通过ID查找

      48.new操作符具体做了什么

      创建一个新的实例对象,并且this变量引用该对象。
      把这个对象的this指向构造函数原型
      继承构造函数原型对象的方法和属性
      返回这个对象this

      49.JSON的了解

      JSON是一种轻量级的数据交换格式。它是基于js的一个子集,数据格式简单,易于读写,
      占用带宽小。

      50.怎么让chrome支持小于12px的文字?

      通过css的transform:scale(0.8)属性。 chrome的私有属性 -webkit-transform:scale(0.8)

      51.现翻书效果可以使用css3中的什么方法?

      transform:rotate()

      52.display:none和visibility:hidden的区别

      display:none是彻底消失,不在文档流中占用位置,浏览器也不会解析该元素。
      visibility:hidden是视觉上消失了,可以理解为透明,但是在文档流中占有位置,浏览器会解析该元素。

      53.position中的relative和absolute的定位原点是什么?

      relative(相对定位):定位的原点是元素本身所在的位置。保留原来的文档位置
      absolute(绝对定位):定位的原点是离自己这一级元素最近的一级position设置absolute或relative的
      父元素的左上角为原点的。脱离标准文档流
      fixed(固定定位):相对于浏览器窗口来定位的,是固定的,不会跟屏幕一起滚动。脱标
      inhert:
      static:

      54.CSS中的link和@import的区别是?

      区别:(1)link是XHTML标签,除了加载CSS外,还可以定义RSS等其他事务。@import属于CSS范畴,只能加载CSS
      (2).link在引入CSS时,在页面载入的同时加载;@import需要等页面完全载入后才加载。

      55.什么是原型?

      每一个javascript对象创建的时候,就会与之关联另一个对象,这个对象就是我们所说的原型
      (prototype),每一个实例对象都会从这个原型继承属性。
      这么说可能会有一些抽象 ,我们来举一个例子
      构造函数在创建实例的过程中,如果去实例中寻找某个属性值的时候,如果有的话就会直接输出,
      如果没有的话,就回去原型对象中查找。
      ··prototype 原型对象:每一个函数都有一个原型对象属性,这个属性指向函数的原型对象。
      ····proto 这是每一个实例对象都有的一个属性,这个属性会指向对象的原型
      ······constructor 每一个原型都会有一个constructor属性,这个属性指向该关联的构造函数。

      2.什么时候会用到原型?
      funciton Person(name,age){
      this.name=name;
      this.age=age;
      this.setName=function(){
      console.log(“我的名字叫”+this.name)
      }
      }
      每次创建一个Person构造函数,为每一个实例对象都添加一个setName方法,也就是构造函数
      每执行一次,就会创建一个新的setName方法
      一个还好,如果创建了上千个实例,这个时候就体现出了原型的好处,可以将这个setName方法
      放到构造函数的prototype中,这个时候只需要创建一个setName,每一个实例都可以访问到。

      3.什么是原型链?
      每一个对象都可以有一个原型,这个原型还可以有它自己的原型,以此类推,会形成一个原型链。
      简单的表达就是:上面说过,如果实例中没有一个属性,会去他的原型中查找,如果他的原型中
      也没有这个属性的话,会到他的原型对象的原型对象中查找,这个 操作就被委托到原型链上去,
      直到最后一个找到到原型时返回null

      56.谈谈你的项目。

      首先这个项目 当初做这个项目的初衷是参加计算机软件大赛 但是后来由于某些原因 项目被搁置了
      但是回头因为项目做了一半嘛 所以又把他拿出来 做全一个项目 后来的话卖给别人当大作业了
      这个项目 首先 酒店用户权限的一个管理系统
      这个项目我是用的技术栈是 vue+element组件+vueRouter路由
      为什么选用element饿了么组件?
      因为我们做的这个项目是关于后台的权限控制,而饿了么组件也是当时饿了么团队,由于当时后台系统业务
      需求开发的一个饿了么桌面组件库,所以我就选用了饿了么组件,来帮助我更快的开发项目。

      项目中,我是用vue-CLI脚手架搭建了项目的基本结构
      1.项目中 我觉得第一个登录页面非常重要 同时我在这上面花费的时间也最多
      首先使用element-ui组件,实现登录页面布局。(el-input el-button el-form表单)
      (1).我需要选用一个记录用户登录状态的token,当用户填写完账号密码之后,向服务器端验证是否正确,
      服务器端验证之后生成该用户的token并且返回。
      (2).将登录成功之后的token存储在本地sessionStorage中,(项目接口其他API的访问 ,必须在登录之后才能
      访问)。这个时候我们需要挂载一个路由导航守卫,也就是i登录之后,判断是否有token,没有token 的话,自动
      重定向到登录页(防止用户没有登录,直接访问页面路径)。
      (3).在用户登录成功之后,我们如果需要再次访问数据库接口,就需要通过axios拦截器,在请求头添加一个
      token,那样每次都携带token去数据库请求接口api。
      (4).退出登录登录按钮,当我们点击推出登录按钮的时候,会清空本地sessionStorage中的token,根据路由
      导航守卫自动重定向到了登录页面。
      (5).整个页面使用IconFont字体图标,el-form表单中有一个rules属性,实现对表单内容的格式验证,还有
      两个button按钮,表单的重置登录按钮,重置按钮,属性resetFields,登录按钮采用防抖的方法,防止对服务器
      发起多次请求。点击登录按钮,调用表单实例的validate函数,进行表单提交的预验证。
      (6)使用axios请求服务器接口之后,返回一个promise对象,所以整个项目中使用async,await来解决这个
      问题。
      (7).登录成功之后,利用组件Message进行一个弹框提示 为了方便以后使用 把 m e s s a g e 挂 载 到 v u e 原 型 上 。 ( 8 ) . 最 后 , 在 登 陆 成 功 的 页 面 中 , 设 置 了 一 个 退 出 按 钮 , 当 你 点 击 退 出 的 时 候 , 自 动 清 空 s e s s i o n S t o r a g e 中 的 t o k e n , 并 且 路 由 重 定 向 到 l o g i n 页 面 ( t h i s . message挂载到vue原型上。 (8).最后,在登陆成功的页面中,设置了一个退出按钮,当你点击退出的时候,自动清空sessionStorage中的 token,并且路由重定向到login页面(this. messagevue8.退退sessionStoragetokenloginthis.router.push(’/login’))
      (9).eslint语法检测 (格式化工具和eslint存在语法冲突) 项目根目录创建一个.prettierrc这是一个json格式
      配置文件 semi:"false"不加分号 singleQuote’:“true”单引号