假如给你一个复杂的功能让你实现,有什么思路写好这个功能?

解决问题之前需要理解问题,找出问题的主干
要求解的是什么? 需要实现的复杂功能是什么?
已知什么? 这个功能的实现逻辑什么是什么?
要满足哪些条件? 实现些逻辑需要什么数据结构?
形成解决思路
根据以往的经验、或者已经掌握的技能和知识构建解决问题的思路。
软件开发的各种设计模式和设计原则都是解决类似问题的基本经验。
执行
按照自己的解题思路,耐心的执行。
软件开发过程可以方便的获取结果的反馈,所以可以在执行的过程中不断的调整。
总结
每次解决完问题,需要把整个过程重新思考总结一下,获取会发现更好的解决方法。
总结整理形成自己实现功能的基本套路,下次遇到类似问题就可以进一步的精进了。

1.js的数据类型
基本数据类型:Number、String、Boolean、Null、 Undefined. es6新增的symbol
引用数据类型:Object,Array,Function
声明变量时不同的内存地址分配:
简单类型的值存放在栈中,在栈中存放的是对应的值
引用类型对应的值存储在堆中,在栈中存放的是指向堆内存的地址
不同的类型数据导致赋值变量时的不同:
简单类型赋值,是生成相同的值,两个对象对应不同的地址
复杂类型赋值,是将保存对象的内存地址赋值给另一个变量。也就是两个变量指向堆内存中同一个对象
BigInt是一种新的数据类型,用来计算大数字的 如何创建并使用BigInt?
要创建BigInt,只需要在数字末尾追加n即可

2.数组的常用方法

下面前三种是对原数组产生影响的增添方法,第四种则不会对原数组产生影响
push() 在后面添加
unshift() 在前面添加
splice() 根据索引的位置后面添加
concat() 连接一个新的数组

下面三种都会影响原数组,最后一项不影响原数组:
pop() 删除最后一个
shift() 删除第一个
splice() 根据索引位置 删除几个就填写数字几
slice() 第一个参数是从索引第几个开始删,第二个参数是从索引第几个结束

即修改原来数组的内容,常用 splice
splice() 第一个参数是索引,第二个参数是删除几个,第三个参数开始是插入元素

即查找元素,返回元素坐标或者元素值
indexOf() 查找元素在数组中的位置并返回索引,没找到返回-1
includes() 查找元素在数组中的位置并返回true,没找到返回false
find() 查找且返回第一个匹配到的元素
排序方法
数组有两个方法可以用来对元素重新排序:
reverse() 翻转
sort() 排序 a-b或者b-a
转换方法 join() 方法接收一个参数,即字符串分隔符,返回包含所有项的字符串

迭代方法(遍历)
常用来迭代数组的方法(都不改变原数组)有如下:
some() 遍历所有元素,有一项满足条件则返回true (相当于逻辑或| | )
every() 遍历所有元素,要所有满足条件才返回true (相当于逻辑与&&)
forEach() 三个参数item(每一项), index(索引), array(原数组)
filter() 只返回满足条件的数组
map() 按照传入的函数返回对应的数组

ES6数组新增方法(注意浏览器兼容)
1.Array.from()
方法是用于类似数组的对象(即有length属性的对象)和可遍历对象转为真正的数组。
2.Array.of()
方法是将一组值转变为数组,参数不分类型,只分数量,数量为0返回空数组。
3.find()
方法返回通过测试(函数内判断)的数组的第一个元素的值。方法为数组中的每个元素都调用一次函数执行。当数组中的元素在测试条件时返回 true 时, find() 返回符合条件的元素,之后的值不会再调用执行函数。如果没有符合条件的元素返回 undefined。
includes( ) 方法用来判断一个数组是否包含一个指定的值,如果是返回 true,否则false。

3.字符串的常用方法

除了常用 + 以及 ${} 进行字符串拼接之外,还可通过 concat

slice()
substr()
substring()

trim()、trimLeft()、trimRight() 清除左右两边的空格
repeat() 接收一个number参数,参数是多少就复制多少次
toLowerCase()、 toUpperCase() 大小写转化

除了通过索引的方式获取字符串的值,还可通过:
chatAt() 返回当前参数索引所在的字符串
indexOf() 从字符串开头去搜索传入的字符串,并返回索引(如果没找到,则返回 -1 )
startWith() includes() 从字符串中搜索传入的字符串,并返回一个表示是否包含的布尔值

4.(重排)回流和重绘以及减少重排和重绘
什么是回流(重排)
当render tree中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建。这就称为回流(reflow)。每个页面至少需要一次回流,就是在页面第一次加载的时候,这时候是一定会发生回流的,因为要构建render tree。在回流的时候,浏览器会使渲染树中受到影响的部分失效,并重新构造这部分渲染树,完成回流后,浏览器会重新绘制受影响的部分到屏幕中,该过程成为重绘。
什么是重绘
当render tree中的一些元素需要更新属性,而这些属性只是影响元素的外观,风格,而不会影响布局的,比如background-color。则就叫称为重绘。
如何减少重排和重绘
改变元素的color、background、box-shadow等属性
重排优化建议:
避免table表格布局
class操作样式
缓存需要修改的DOM元素
尽量只修改position:absolute或fixed元素,对其他元素影响不大

5.网页生成过程:
1.HTML被HTML解析器解析成DOM 树
2.css则被css解析器解析成CSSOM规则树
3.结合DOM树和CSSOM树,生成一棵渲染树(Render Tree)
4.生成布局(flow),即将所有渲染树的所有节点进行平面合成
5.浏览器讲以上数据通知CPU显示在屏幕上

6.JS内存泄漏与垃圾回收机制
内存泄漏:JavaScript 中的内存管理是自动执行的,而且是不可见的。我们创建基本类型、对象、函数……所有这些都需要内存。不再用到的内存,没有及时释放,内存满了就叫做内存泄漏。(造成内存泄漏常见的有闭包,闭包中的变量没有及时清除,还有定时器,定时器引用后也没有及时清除)
垃圾回收机制:解决内存的泄露,垃圾回收机制会通过js的执行环境定期(周期性)找出那些不再用到的内(变量),然后释放其内存。现在各大浏览器通常采用的垃圾回收机制有两种方法:标记清除,引用计数(手动设置变量=null)

7.对于闭包的理解
闭包: 闭包的定义是比较抽象的,我个人的理解就是一个函数可以访问另一个函数内部的函数和变量就是闭包
闭包的作用: 1.创建私有变量 2.延长变量的生命周期
闭包的应用场景:防抖和节流,使用柯里化函数
闭包的缺点:工作中我们应该尽量避免闭包,内存消耗比较大,会导致内存泄漏

8.如何清除浮动
1.直接设置父元素的高度
2.为父元素设置overflow属性
3.添加div标签在最后面,设置clear:both
4.给父元素也设置浮动
5.用before,after 伪元素,设置content:“”,display:block

9.BFC的理解
BFC (Block Formatting Context),即块级格式化上下文,它是页面中的一块独立的渲染区域,目的是形成一个相对于外界完全独立的空间,让内部的子元素不会影响到外部的元素,外部的其他元素也影响不了内部的元素
bfc的作用:
1.可以解决外边距重叠 (给父元素设置overflow:heddle)
2.可以清除浮动 (给父元素设置overflow:heddle)
3.可以阻止元素被浮动的元素覆盖,设置两栏自适应布局 (给没有设置浮动的元素设置overflow:heddle)
4.自适应多栏布局

10.防抖和节流:
防抖(debounce):在短时间内多次触发同一个函数,只执行最后一次。
举例:英雄在回城的时候不管按多少次B,只会执行最后一次
应用场景:
1.表单输入验证
2.表单输入触发搜索 ajax
3.resize/scroll/touch/mouseove 事件
节流阀(throttle):多次触发同一个函数,同一段时间内只执行一次。
举例:英雄的技能在固定的时间内才能出发,不管按多少次到了时间才执行
应用场景:
1.获取验证码很多都会限制 60s 的时间,在 60s 内再次获取验证码是无效,只能获取一次。下个60s才能再次获取。
2.resize/scroll/touch/mouseove 事件
3.表单输入联想

13.this的指向情况:
1.以匿名函数形式调用时,this永远都是window对象
2.以对象方法调用时,this是调用方法的对象
3.以构造函数形式调用时,this是构造函数的实例
4.以call和apply和bind调用时,this是绑定的那个对象
New关键字做了什么?
1.创建一个新对象(开辟一个内存)
2.将构造函数的作用域赋值给新对象 (也就是this指向新对象)
3.执行构造函数中的代码(为这个新对象添加属性)
4.把结果返回给新的对象

14. typeof和intansof的作用
typeof一般用来判断简单数据类型 (返回数据类型) typeof ‘1’ // ‘string’
intansof通过原型链的方式来判断引用数据类型 (返回布尔值) car instanceof String // true
如何区分数组和对象:Object.prototype.toString.call( )可以检测通用的数据类型,可以采用 Object.prototype.toString.call(Object.prototype.toString.call(‘1’) // “[object String]” )

15.构造函数,原型,和原型链
构造函数: 批量创建对象的函数就是构造函数,可以用new关键字来调用,class是一个语法糖,ES6的规范
原型:
①所有引用类型都有一个__proto__(隐式原型)属性,指向它构造函数的prototype
②所有函数都有一个prototype(显示原型)属性,属性值是一个普通的对象
var a = [1,2,3];
a.proto === Array.prototype; // true
原型链:
当访问一个对象的某个属性时,会先在这个对象本身属性上查找,如果没有找到,则会去它的__proto__隐式原型上查找,即它的构造函数的prototype,如果还没有找到就会再在构造函数的prototype的__proto__中查找,这样一层一层向上查找,如果找到Object上面还没找到,就会返回null,我们称为原型链。
注意:对象是没有prototype属性,只有方法才有prototype属性。

16.事件冒泡和事件委托
事件模型
事件模型可以分为三种:
原始事件模型(DOM0级)
标准事件模型(DOM2级)
IE事件模型(基本不用)
事件流
冒泡:冒泡就是事当点击事件触发后,会从当前目标一级一级向上传播,直到传播到跟元素
dom的事件流: 捕获阶段,目标阶段,冒泡阶段
阻止默认行为 :event.preventDefault()
阻止冒泡事件 : event.stopPropagation()
上述两个操作可以合并为:return false;
事件委托:就是利用冒泡的原理,把事件加到父级上,通过判断事件来源的子集,执行相应的操作,事件委托首先可以极大减少事件绑定次数,提高性能;其次可以动态的添加子元素和删除子元素 ,示例:ul>li*10 直接给ui绑定事件,li都能够触发
事件委托的关系是将子元素的事件委托到父元素上。
冒泡我们也可以用事件委托的方式

17.var let const 三种申明变量的区别:
Var: 1.var声明的变量具备全局变量函数内部的程序可以读取函数外部的var 声明的变量,但是函数外部不可以读取函数内部的变量;
2.会出现变量提升
3.var 声明的数据是可变性的
Let: 1.let所声明的变量只在let命令所在的代码块内有效。(块级作用域)
2.let命令不存在变量提升
3.let声明变量存在暂时性死区(即变量会绑定某个区域,不受外部影响)
Const: const声明一个只读的常量。一旦声明,常量的值就不能改变。const声明的变量不得改变值,这意味着,const一旦声明变量,就必须立即初始化,不能留到以后赋值

18.js中的继承方法:
一个原本没有某些方法或属性的对象,统一写方法,就能拿到另外对象的属性和方法
1.改变this指向继承(构造函数继承):继承构造函数中的属性和方法
2.原型对象继承:继承原型
3.原型链继承:通过给Child设置原型为Parent的实例的方式,给Child添加了一层原型链的方式
4.混合继承:构造函数继承+原型对象继承(既能继承构造函数又能继承原型,方便传参,多继承)
5.ES6的class继承: (constructor函数创建属性和方法+子类用extends继承父类+子类用super将参数指向父类 )

19.src与herf的区别
Src:指向外部资源的位置,请求的资源会下载到当前的元素中,当浏览器解析到src引入的资源时,会停止解析,等解析完毕后再继续执行
Herf:指向网络资源的位置,用来建立当前元素与资源的连接,当浏览器解析到herf引入的资源时会继续下载,然后继续执行当前的文档

20.前端如何解决跨域
1.什么是跨域?
跨域实际上也就是非同源策略请求,域名,协议,端口,三者全部相同就是同源,其中一个不同就是跨域
2.什么是同源策略?
同源策略:所谓同源是指,域名,协议,端口相同。
3.跨域解决方案:
Jsonp:所谓jsonp就是前端通过script标签不受同源策略的影响,请求数据的时候传递一个回调函数,让后端把数据放到回调函数里面返回给前端
Cors:需要后端的配合,所谓的CORS就是服务端通过设置请求头实现,告诉浏览器可以跨域请求
Nginx反向代理:现在大多数都是前后端分离模式,请求数据必然会产生跨域,反向代理相当于一个中间件,工作中用的最多的就是webpack来配置实现反向代理

21.session和jwt的原理
session的原理:用户登录通过后,服务器生成用户相关的数据保存在Session(当前会话)中,并将对应的Cookie发给浏览器, 用户在每次发送请求时,都会携带cookie用于验证,当用户主动退出或者到期销毁后,session和cookei也就无效了
jwt的原理:用户登录通过后,服务器生成用户相关的数据,经过加密后生成Token字符串发给浏览器, 浏览器存放于LoalStorage或SessionStorage下,用户在下次浏览器请求时,通过在Authorization字段中携带token,就能进行访问,当用户主动销毁或token过期,token就不存在了

23.es6新增的属性和方法
一.扩展运算符
二.Let,const的申明变量的方法
三.基本数据类型,Symbol 一个独一无二的变量
四.Set( )方法,类似一个数组,但是他的成员没有重复值
五.Async,await语法糖
六.Promise(里面保存着某个未来才会结束的事件).then正确时的回调函数…catch错误时的回调函数,可以解决回调地狱,主要用来发起ajax异步请求
七.属性名表达式 :ES6 允许字面量定义对象时,将表达式放在括号内
const a = {
‘first word’: ‘hello’,
[lastWord]: ‘world’
};
a[‘first word’] // “hello”
a[lastWord] // “world”
a[‘last word’] // “world”
八.super关键字
this 关键字总是指向函数所在的当前对象,ES6 又新增了另一个类似的关键字 super ,指向当前对象的原型对象
九.属性的遍历:
Object.keys(obj):返回一个数组,返回的是对象的属性名
Object.values(obj):返回一个数组,返回的是对象的属性的属性值
Object.setPrototypeOf({},null ) 方法用来设置一个对象的原型对象
Object.getPrototypeOf() 用于读取一个对象的原型对象
十.严格模式
只要函数参数使用了默认值、解构赋值、或者扩展运算符,那么函数内部就不能显式设定为严格模式, 否则会报错
严格模式只需要在函数内第一行设置:'use strict’即可

24.递归的应用场景
递归:如果一个函数在内部自己调用自己,这个函数就是递归函数
Vue的 树型选择控件时,服务端返回的数据
递归必须要有一个基本条件来打断他的循环,否则他就会不停的调用自身。

25.普通函数和箭头函数的区别
1.箭头函数是匿名函数,不能作为构造函数,不能使用new
2.箭头函数不绑定arguments,取而代之用rest参数…解决
3.箭头函数不绑定this,会捕获其所在的上下文的this值,作为自己的this值
4.箭头函数通过 call() 或 apply() 方法调用一个函数时,只传入了一个参数,对 this 并没有影响。
5.箭头函数没有原型属性
6.箭头函数不能当做Generator函数,不能使用yield关键字命令
7.箭头函数的 this永远指向其上下文的 this ,任何方法都改变不了其指向,如call() , bind() , apply()
8.普通函数的this指向调用它的那个对象

26.函数的arguments
是一个伪数组,有数组的length属性,有索引!但是不能用数组的方法
下面三种方法可以转为数组
let args=Array.prototype.slice.call(arguments )–let args = Array.from(arguments)-let args = […arguments];
Vue中functional为true,表示该组件为一个函数式组件(函数式组件:没有data状态,没有响应式数据,只会接收props属性, 没有this,他就是一个函数 (render函数渲染))

27.回调函数是什么?
将函数作为一个参数传递到另一个函数里面就叫回调函数,当一个主函数执行完了过后就会执行这个函数

28.css中的继承
可继承的属性:
字体系列属性
文本系列属性
继承中比较特殊的几点:
a标签的字体颜色不能被继承
h1-h6标签字体的大下也是不能被继承的
无继承的属性
display
文本属性:vertical-align、text-decoration
盒子模型的属性:宽度、高度、内外边距、边框等
背景属性:背景图片、颜色、位置等
定位属性:浮动、清除浮动、定位position等
生成内容属性:content、counter-reset、counter-increment
轮廓样式属性:outline-style、outline-width、outline-color、outline

29.Css 预编译语言:(sass less stylus ) 可以私有化样式,嵌套
虽然各种预处理器功能强大,但使用最多的,还是以下特性:
变量(variables)
作用域(scope)
代码混合( mixins)
嵌套(nested rules)
代码模块化(Modules)

30.css3实现动画的方法
transition(过 度)
用于设置元素的样式过度,和animation有着类似的效果,但细节上有很大的 不同
transform(变 形)
用于元素进行旋转、缩放、移动或倾斜,和设置样式的动画并没有什么关系,
就相当于color一样用来设置元素的“外表”
translate(移 动)
只是transform的一个属性值,即移动
animation(动 画)
用于设置动画属性,他是一个简写的属性,包含6个属性

32.BOM对象有哪些?列举window对象?
(1)window对象 ,是JS的最顶层对象,其他的BOM对象都是window对象的属性;
(2)document对象,文档对象;
(3)location对象,浏览器当前URL信息;
(4)navigator对象,浏览器本身信息;
(5)screen对象,客户端屏幕信息;
(6)history对象,浏览器访问历史信息;

33.你做页面在哪些浏览器测试过?这些浏览器的内核是什么?
(1)IE浏览器:Trident内核
(2)火狐浏览器:Gecko内核
(3)Safari浏览器:Webkit内核
(4)Opera浏览器:以前是Presto内核,现在是Blink内核
(5)谷歌浏览器:Blink内核
浏览器的内核是分为两个部分的,一是渲染引擎,另一个是JS引擎。现在JS引擎比较独立,内核更加倾向于说渲染引擎。

34.说说em/px/rem/vh/vw区别
px:绝对单位,页面按精确像素展示
em:相对单位,基准点为父节点字体的大小,如果自身定义了 font-size 按自身来计算,整个页面内 1em 不是一个固定的值
rem:相对单位,可理解为 root em , 相对根节点 html 的字体大小来计算
vh、vw:主要用于页面视口大小布局,在页面布局上更加方便简单 如果要实现阶梯式响应式布局,屏幕尺寸一旦发生变化,页面元素的大小随之改变1vw代表着屏幕宽度的百分之一,1vh代表着屏幕高度的百分之一

35.实现元素水平垂直居中的方式:
利用定位+margin:auto
利用定位+margin:负值
利用定位+transform
flex布局
内联元素居中布局
水平居中
行内元素可设置:text-align: center
flex布局设置父元素:display: flex; justify-content: center
垂直居中
单行文本父元素确认高度:height === line-height
多行文本父元素确认高度:disaply: table-cell; vertical-align: middle6

36.flex布局:
我们能够通过 flex 简单粗暴的实现元素水平垂直方向的居中,以及在两栏三栏自适
应布局中通过 flex 完成,这里就不再展开代码的演示
包括现在在移动端、小程序这边的开发,都建议使用 flex 进行布局
容器的属性:
flex-direction (决定主轴的方向)
flex-wrap (是否换行)
flex-flow (主轴方向和换行的简写)
justify-content (水平方向的位置)
align-items (垂直方向的位置)
align-content (多根轴线的对齐方式)
容器的成员属性:
order (排列顺序。数值越小,排列越靠前,默认为0
)
flex-grow (容器没设置换行时,容器宽度不够分时,可以分剩余空间)
flex-shrink
flex-basis
flex
align-self

37.响应式布局和原理
1.响应式设计的基本原理是通过媒体查询检测不同的设备屏幕尺寸做处理,为了处理移动端,页面头部必须有 meta 声明 viewport
2.实现响应式布局的方式有如下:
媒体查询 (使用 @Media 查询,可以针对不同的媒体类型定义不同的样式)
百分比% (比如当浏览器的宽度或者高度发生变化时,通过百分比单位,可以使得浏览器中的组件的宽和高随着浏览器的变化而变化,从而实现响应式的效果 )
vw/vh (vw 表示相对于视图窗口的宽度, vh 表示相对于视图窗口高度。 任意层级元素,在使用 vw 单位的情况下, 1vw 都等于视图宽度的百分之一)
rem (rem 是相对于根元素 html 的 font-size 属性,默认情况下浏览器字体大小为 16px ,
此时 1rem = 16px,可以使用媒体查询,针对不同设备分辨率改变html font-size 的值 )
我们还可以利用主流 UI 框架,如: element ui 、 antd 提供的栅格布局实现响应式

38.JavaScript 中的类型转换机制
强制转换(显示转换)
Number() 将任意类型的值转化为数值

parseInt() 只识别数字 parseInt(‘32a3’) //32

String() 可以将任意类型的值转化成字符串

Boolean()可以将任意类型的值转为布尔值
自动转换(隐示转换)
自动转换布尔值:
undefined null false +0 -0 NaN “” 这几种会被转化成 false ,其他都换被转化成 true
自动转换成字符串 在 + 运算中,一旦存在字符串,则会进行字符串拼接操作

自动转换成数值 除了 + 有可能把运算子转为字符串,其他运算符都会把运算子自动转成数值
(相等)和=(全等)的区别:
左右数据类型不相同的时候:=(全等)不能对数据进行隐式转换,直接返回false
(相等)会默认转换为一致的数据类型再进行比较
隐式转换的规则:
NaN与任何值都不相等
nullundefined(true) null=undefeated(false) 「null和undefeated与任何值都不想
NaN与任何值相加都是NaN
对象==字符串,隐式转换默认会把对象转为字符串(toString方法)
剩余的所以情况都是转换为数字(Number)

39.js的深拷贝和浅拷贝
浅拷贝
浅拷贝,指的是创建新的数据,这个数据有着原始数据属性值的一份精确拷贝
如果属性是基本类型,拷贝的就是基本类型的值。如果属性是引用类型,拷贝的就是内存地址
在 JavaScript 中,存在浅拷贝的现象有:
1.Object.assign
2.Array.prototype.slice() , Array.prototype.concat()
3.使用拓展运算符实现的复制
深拷贝
深拷贝开辟一个新的栈,两个对象属完成相同,但是对应两个不同的地址,修改一个对象的属性,不会 改变另一个对象的属性
常见的深拷贝方式有:
1.用lodash第三方 _.cloneDeep()
2.jQuery.extend()
3.JSON.parse(JSON.stringify() )
4.手写循环递归

40.JavaScript中执行上下文和执行栈、作用域链是什么
执行上下文的类型分为两种:
全局执行上下文:只有一个,浏览器中的全局对象就是 window 对象, this 指向这个全局对象 (只有全局上下文(的变量)能被其他任何上下文访问 )
函数执行上下文:存在无数个,只有在函数被调用的时候才会被创建,每次调用函数都会创建一个新的执行上下文 (函数创建的上下文是私有变量,只有在自己的作用域内能访问)
执行栈 :
执行栈,也叫调用栈,具有(后进先出)结构,用于存储在代码执行期间创建的所有执行上下文
作用域链:
作用域链就是代码的执行环境,全局执行环境就是全局作用域,函数的执行环境就是私有作用域。比如一个父函数内部定义了一个子函数,那么子函数的上级作用域就是那个父函数
当在函数内部中。需要访问一个变量的时候,首先会访问函数本身的变量对象。如果没有找到 就会到他的上一级作用域找,直到找到那个变量或者最终到全局作用域

41.Javascript本地存储的方式和区别
方式:
cookie (每次携带者请求中,存储大小4kb,主要用于设置tokey的过期时间,存储时间跟设置过期时间有关,即使窗口或浏览器关闭也存在,除非时间到期 )
sessionStorage (存储在本地,存储大小5MB,不手动清除一直存在,存的是字符串)
localStorage (存储在本地,存储大小5MB,页面关闭就清除,存的是字符串)
indexedDB (存储大量数据的情况、在线文档(富文本编辑器)保存编辑历史的情况,推荐使用 indexedDB )
区别:
关于 cookie 、 sessionStorage 、 localStorage 三者的区别主要如下:
存储大小: cookie 数据大小不能超过 4k , sessionStorage 和 localStorage 虽然也有存储大小的限制,但比 cookie 大得多,可以达到5M或更大
有效时间: localStorage 存储持久数据,浏览器关闭后数据不丢失除非主动删除数据;
sessionStorage 数据在当前浏览器窗口关闭后自动删除;
cookie 设置的 cookie 过期时间之前 一直有效,即使窗口或浏览器关闭

42.说说地址栏输入 URL 敲下回车后发生了什么
六个步骤:
URL解析 (判断是否是合法的地址? 协议/域名/端口/路径/请求的资源)
DNS 查询 (访问的ip地址存不存在)
TCP 连接 (进行三次握手,通过相互回应,确定连接)
HTTP 请求 (确定连接后发送具体的请求内容? 方法/url地址/协议版本/请求文本类型/携带的参数)
响应请求 (接收到请求后响应给浏览器的请求内容)
页面渲染 (解析html生成dom树,解析css生成css规则树,和并html和css生成render树,布局和绘制render树,浏览器把数据发给CPU显示在屏幕上)

43.bind、call、apply 区别?如何实现一个bind?
apply 、 call 、 bind 三者的区别在于:
三者都可以改变函数的 this 对象指向
三者第一个参数都是 this 要指向的对象,如果如果没有这个参数或参数为 undefined 或 null ,则默认指向全局 window
三者都可以传参,但是 apply 是数组,而 call 是参数列表,且 apply 和 call 是一次性传入参数,而 bind 可以分为多次传入
bind 是返回绑定this之后的函数, apply 、 call 则是立即执行

44.事件循环机制(js单线程)
首先js是一个单线程,js在执行的过程中,先执行同步任务,在执行异步任务,执行过程中会把异步任务放置到任务队列中,任务队列里面又分为宏任务和微任务,先执行微任务,执行微任务的时候如果又发现微任务,会继续执行微任务,然后在执行宏任务,这样就是事件循环
异步和同步的区别:异步是不会阻塞代码执行的,同步是会阻塞代码执行,等执行完毕再去执行后面的代码

46.get和post传参数的区别?
1.get在浏览器回退不会再次请求,而post会
2.get 传送的数据长度有限制,post 没有
3.get 通过 url 传递,在浏览器地址栏可见,post 是在报文Request body中传递
4.get参数暴露在地址栏不安全,post放在报文内部更安全
适用场景:
post 一般用于表单提交
get 一般用于简单的数据查询,严格要求不是那么高的场景

47.http和https的区别
1.HTTP 的URL 以http:// 开头,而HTTPS 的URL 以https:// 开头
2.HTTP 是不安全的,而 HTTPS 是安全的
3.HTTP 标准端口是80 ,而 HTTPS 的标准端口是443
4.在OSI 网络模型中,HTTP工作于应用层,而HTTPS 的安全传输机制工作在传输层
5.HTTP 无法加密,而HTTPS 对传输的数据进行加密
6.HTTP无需证书,而HTTPS 需要CA机构wosign的颁发的SSL证书

48.http返回的状态码
200响应成功 (成功状态码)
301永久重定向 (重定向状态码)
302临时重定向 (重定向状态码)
304资源缓存 (重定向状态码)
403服务器禁止访问 (客户端错误状态码
404服务器资源未找到 (客户端错误状态码
500 502服务器内部错误 (服务器错误状态码)
504 服务器繁忙 (服务器错误状态码)

49.前端性能优化的几种方式

  1. 浏览器缓存
  2. 防抖、节流
  3. 资源懒加载、预加载
    4.开启Nginx gzip压缩
    三个方面来说明前端性能优化
    一: webapck优化与开启gzip压缩
    1.babel-loader用 include 或 exclude 来帮我们避免不必要的转译,不转译 node_moudules中的js文件
    其次在缓存当前转译的js文件,设置loader: ‘babel-loader?cacheDirectory=true’
    2.文件采用按需加载等
    3.具体的做法非常简单,只需要你在你的 request headers 中加上这么一句:
    accept-encoding:gzip
    4.图片优化,采用svg图片或者字体图标
    5.浏览器缓存机制,它又分为强缓存和协商缓存
    二:本地存储——从 Cookie 到 Web Storage、IndexedDB
    说明一下SessionStorage和localStorage还有cookie的区别和优缺点
    三:代码优化
    1.事件代理
    2.事件的节流和防抖
    3.页面的回流和重绘
    4.EventLoop事件循环机制
    5.代码优化等等

50.原生的ajax实现过程
1.创建 Ajax 的核心对象 XMLHttpRequest 对象
2.通过 XMLHttpRequest 对象的 open() 方法与服务端建立连接
3.构建请求所需的数据内容,并通过 XMLHttpRequest 对象的 send() 方法发送给服务器端
4. 通过 XMLHttpRequest 对象提供的 onreadystatechange 事件监听服务器端你的通信状态
5.接受并处理服务端向客户端响应的数据结果
6.将处理结果更新到 HTML 页面中

51.axios是什么?怎么用?
axios是基于promise的一个异步请求,一般用于登录流程,设置baseURL基地址,有请求和响应拦截,判断用户是否携带toekn
在vue项目中安装axios包,然后导入,创建一个baseURL基地址,请求拦截器和响应拦截器主要是判断用户是否携带token,
1.请求拦截器:
axios.interceptors.request.use(function (config) {
// 这里写发送请求前处理的代码
return config;
}, function (error) {
// 这里写发送请求错误相关的代码
return Promise.reject(error);
});
2.响应拦截器:
axios.interceptors.response.use(function (response) {
// 这里写得到响应数据后处理的代码
return response;
}, function (error) {
// 这里写得到错误响应处理的代码
return Promise.reject(error);
});

52.vue项目中如何解决跨域的
使用最多就是Porxy的反向代理:
amodule.exports = {
devServer: {
host: ‘127.0.0.1’,
port: 8084,
open: true,// vue项目启动时自动打开浏览器
proxy: {
‘/api’: { // ‘/api’是代理标识,用于告诉node,url前面是/api的就是使用代理的
target: “http://xxx.xxx.xx.xx:8080”, //目标地址,一般是指后台服务器地

changeOrigin: true, //是否跨域
pathRewrite: { // pathRewrite 的作用是把实际Request Url中
的’/api’用""代替
‘^/api’: “”
}
}
}
}
}

53.websocket是什么?
WebSocket,也是一种网络传输协议
客户端和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输
http则需要tcp三次握手才能建立连接
http发送请求客户端是主动的,服务端是被动的,而websocket发送请求是相互的
http就像是微信发消息,需要你来我往,而websocket就像是打语音电话
一、websocket优点
1较少的控制开销:数据包头部协议较小,不同于http每次请求需要携带完整的头部
2更强的实时性:相对于HTTP请求需要等待客户端发起请求服务端才能响应,延迟明显更少
3保持创连接状态:创建通信后,可省略状态信息,不同于HTTP每次请求需要携带身份验证
4.更好的二进制支持:定义了二进制帧,更好处理二进制内容
5.支持扩展:用户可以扩展websocket协议、实现部分自定义的子协议
6.更好的压缩效果:Websocket在适当的扩展支持下,可以沿用之前内容的上下文,在传递类似的 数据时,可以显著地提高压缩率
二、应用场景
.基于 websocket 的事实通信的特点,其存在的应用场景大概有:
.弹幕
.媒体聊天
.协同编辑
.基于位置的应用
.体育实况更新
.股票基金报价实时更新

54.ES6的promise
1.promise译为承诺,指得是未来的一个承诺!用来解决回调地狱和发送异步请求
2.promise 对象仅有三种状态 :
pending (进行中) fulfilled (已成功) rejected (已失败)
3.Promise 对象是一个构造函数,用来生成 Promise 实例,Promise 构造函数接受一个函数作为参数,该函数的两个参数分别是 resolve 和 reject
4.promise的实例有三个方法:
then( ) 该方法返回的是一个新的 Promise 实例,也就是 promise 能链式书写的原因
catch( ) 该方法用于指定发 生错误时的回调函数
finally( ) 方法用于指定不管 Promise 对象最后状态如何,都会执行的操作
简单描述一下promise
primise是异步编程的一种解决方案,可以解决回调地狱,他有三个状态,一个是等待每一个是成功,还有一个是失败。它可以获取异步操作的信息,他接收一个参数,这个参数是函数,这个函数接收两个参数,这两个参数也是函数,一个resolve 一个 reject,一个是异步执行成功之后的回调 一个是 失败后的回调,.then可以捕捉到promise执行成功和失败,然后执行相应的成功函数或者失败函数,

55.如何理解vue的双向数据绑定?
1.首先Vue是利用MVVM来实现的:
M是数据层model
V是视图层view
VM是业务逻辑,是vue框架的核心,它负责将数据与视图关联起来
2.当vue中data的数据发生改变,会触发v-bind,页面视图也会发生改变,视图发生改变会触发v-on,也会影响到数据更新,
3.vue的双向数据绑定(响应式原理)是通过数据劫持,结合发布者和订阅者的方式来实现的:具体是用Object.defeneProperty( )方法劫持属性,用set和get方法去操作属性,并返回这个对象,vue内部监听到数据发生变化,会通知到每个订阅者(DOM元素),接下来每个订阅者会根据最新的数据,用update方法更新自己的内容 dep就是发布者,watcher是订阅者
如何理解 Vue 的单向数据流
1.数据总是从父组件传到子组件,子组件没有权利修改父组件传过来的数据,只能请求父组件对原始数据进行修改。这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。
2.如果实在要改变父组件的 prop 值 可以再 data 里面定义一个变量 并用 prop 的值初始化它 之后用$emit 通知父组件去修改
Vue 如何检测数组变化
数组考虑性能原因没有用 defineProperty 对数组的每一项进行拦截,Vue 中修改数组的索引和长度是无法监控到的,而是选择对 7 种数组(push,shift,pop,splice,unshift,sort,reverse)方法进行重写

56.如何理解spa单页面
因为近几年比较的流行的mvvm框架,非常适合做SPA单页面,像我们熟知的JS框架如react,vue都属于SPA。
SPA单页面是将所有的活动都放在一个页面上,仅在该Web页面初始化时加载相应的HTML、JavaScript 和 CSS。一旦页面加载完成,SPA 不会因为用户的操作而进行页面的重新加载或跳转;取而代之的是利用路由机制实现 HTML 内容的变换,UI 与用户的交互,避免页面的重新加载。
优点:
• 用户体验好、快,内容的改变不需要重新加载整个页面,避免了不必要的跳转和重复渲染;
• 基于上面一点,SPA 相对对服务器压力小;
• 前后端职责分离,架构清晰,前端进行交互逻辑,后端负责数据处理;
缺点:
• 初次加载耗时多:为实现单页 Web 应用功能及显示效果,需要在加载页面的时候将 JavaScript、CSS 统一加载,部分页面按需加载;
• 前进后退路由管理:由于单页应用在一个页面中显示所有的内容,所以不能使用浏览器的前进后退功能,所有的页面切换需要自己建立堆栈管理;
• SEO 难度较大:由于所有的内容都在一个页面中动态替换显示,所以在 SEO 上其有着天然的弱势”

57.Vue的slot插槽
插槽就是来接收父组件的内容和数据的,父组件有内容就显示父组件的内容,没有内容就显示子组件的默认内容
内容显示的位置是由子组件决定的,子组件放在哪个位置,就在对应的位置显示
1.匿名插槽
子组件
父组件父传子的内容
2.具名插槽
子组件
父组件

父传子的内容

3.作用域插槽 | 带数据的插槽
子组件
父组件

{{item}}

58.Vue中清空表单的内容
this. r e f s . r u l e F o r m R e f . r e s e t F i e l d s ( ) t h i s . R u l e F o r m = t h i s . refs.ruleFormRef.resetFields( ) this.RuleForm = this. refs.ruleFormRef.resetFields()this.RuleForm=this.options.data( ).RuleForm

60.Vue利用sync修饰符关闭新增弹层
1.传统的方法:
子组件
this. e m i t ( ′ c h a n g e d i a l o g ′ , f a l s e ) / / 触 发 事 件 父 组 件 < c h i l d @ c h a n g e d i a l o g = " m e t h o d " : s h o w D i a l o g = " s h o w D i a l o g " / > m e t h o d ( v a l u e ) t h i s . s h o w D i a l o g = v a l u e 2. s y n c 语 法 糖 方 法 : 子 组 件 u p d a t e : 固 定 写 法 ( u p d a t e : p r o p s 名 称 , 值 ) t h i s . emit('changedialog', false) //触发事件 父组件 <child @changedialog="method" :showDialog="showDialog" /> method(value) { this.showDialog = value } 2.sync语法糖方法: 子组件 update:固定写法 (update:props名称, 值) this. emit(′changedialog′,false)//触发事件父组件<child@changedialog="method":showDialog="showDialog"/>method(value)this.showDialog=value2.sync语法糖方法:子组件update:固定写法(update:props名称,值)this.emit(‘update:showDialog’, false) //触发事件
父组件 sync修饰符

61.Vue中的父子通信详细用法
1.子组件接收父组件传递的数据:
props: {
trreNode: { //父组件传值必须要用trreNode名字
type: Object, //父组件要传对象
required: true //父组件为必传
}
}
2.子组件让父组件委托处理事件(调用父组件的方法):
this. e m i t ( ′ a d d D e p t s ′ , ) 3. 子 组 件 给 父 组 件 传 值 t h i s . emit('addDepts',) 3.子组件给父组件传值 this. emit(′addDepts′,)3.子组件给父组件传值this.emit(‘addDepts’,sonvalue)
4.父组件给子组件传值

6.父组件处理子组件委托的事件
<child :trreNode=“data” @addDepts=‘father(sonvalue)’ />
Methods:{
father(sonvalue){}
}
7.父组件调用子组件的方法
this.$refs.sonRef.getList(father.id)

62.Vue使用三元表达动态切换标题
直接把这个判断方法动态绑定到需要判断的节点上
computed: {
showTitle ( ) {
return this.formData.id ? ‘编辑部门’ : ‘新增子部门’
}
},

63.在beforeDestroy钩子函数中销毁定时器和viedeo
beforeDestroy( ){
This.setTimeOut=null
}

64.赋值时两种方法实现深拷贝
1.ES6的新语法解构
this. r e f s . d i a l o g E d i t . a r t i c l e R u l e F o r m = . . . r o w 2. 用 J S O N 转 换 t h i s . refs.dialogEdit.articleRuleForm = { ...row } 2.用JSON转换 this. refs.dialogEdit.articleRuleForm=...row2.用JSON转换this.refs.dialogEdit.articleRuleForm = JSON.parse(JSON.stringify(row))

65.Vue中为什么data必须是一个函数
首先App页面根实例对象 data 可以是对象也可以是函数(根实例是单例),不会产生数据污染情况
因为一个组件可能多个地方用到,如果data是一个对象,那么数据可能会因为对象的引用类型特性,发生改变,导致数据污染,为了保证组件的私有性和复用性,防止多个组件实例对象之间共用一个 data,改变数据,所以组件的 data 必须为函数

66.瀑布流的实现方式
设定每一列图片的宽度和间距
获取当前窗口的总宽度,从而根据图片宽度去旁段分成几列
获取所有图片元素,定义一个空数组来保存高度
遍历所有容器,开始判断  当页面加载完成,或页面宽度发生变化时,调用函数。
如果当前处于第一行时: 直接设置图片位置【 即 top为间距的大小,left为(当前图片的宽度+间距) * 当前图片的值+间距大小 】,并保存当前元素高度。
如果当前不处于第一行时:进行高度对比,通过遍历循环,拿到最小高度和相对应的索引,设置图片位置【 即 top为最小高度值+间距*2,left为 (当前图片的宽度+间距) * 索引 值+间距大小)】,并修改当前索引的高度为当前元素高度。
当页面加载完成,或页面宽度发生变化时,调用函数。

67.Vue中watch和computed的区别
computed有缓存,不支持异步,只有当计算值变化才会被调用
watch没有缓存,支持异步,watch 监听到值的变化就会执行回调,在回调函数中可以进行一些逻辑操作,监听的函数接收两个参数,第一个是最新的值第二个是旧的值
Ps:计算属性一般用在模板渲染中,某个值是依赖了其它的响应式对象甚至是计算属性计算而来;而侦听属性适用于观测某个值的变化去完成一段复杂的业务逻辑

68.v-show与v-if的区别和使用场景
1.区别:
vue 中 v-show 与 v-if 的作用效果是相同的(不含v-else),都能控制元素在页面是否显示,v-if的隐藏是直接操作dom元素,v-show的隐藏是给dom设置display为none
2使用场景:
1v-if 与 v-show 都能控制 dom 元素在页面的显示
v-if 相比 v-show 开销更大的(直接操作 dom 节点增加与删除)
如果需要非常频繁地切换,则使用 v-show 较好
如果在运行时条件很少改变,则使用 v-if 较好
display:none、visibility:hidden 和 opacity:0 之间的区别?

69.Vue的生命周期
vue生命周期共分为四个阶段
一:实例创建
二:DOM渲染
三:数据更新
四:销毁实例
共有八个基本钩子函数
1.beforeCreate --创建前触发的行为:vue实例的挂载元素$el和数据对象data都为undefined,还未初始化。在此阶段可以做的事情:加loading事件

2.created --创建后触发的行为:vue实例的数据对象data有了,$el还没有
在此阶段可以做的事情:解决loading,请求ajax数据为mounted渲染做准备

3.beforeMount --渲染前触发的行为:vue实例的$el和data都初始化了,但还是虚拟的dom节点,具体的data.filter还未替换在此阶段可以做的事情:。。。

4.mounted --渲染后触发的行为:vue实例挂载完成,data.filter成功渲染
在此阶段可以做的事情:配合路由钩子使用

5.beforeUpdate --更新前触发的行为:data更新时触发
在此阶段可以做的事情:。。。

6.updated —更新后触发的行为:data更新时触发在此阶段可以做的事情:数据更新时,做一些处理(此处也可以用watch进行观测)

7.beforeDestroy —销毁前
触发的行为:组件销毁时触发在此阶段可以做的事情:可向用户询问是否销毁

8.destroyed —销毁后
触发的行为:组件销毁时触发,vue实例解除了事件监听以及和dom的绑定(无响应了),但DOM节点依旧存在在此阶段可以做的事情:组件销毁时进行提示

70.Vue的v-for和v-if的作用和优先级
一、作用 :
1.v-if用于条件渲染,当条件为true时渲染这块区域
2.v-for 指令是基于一个数组来渲染一个列表,v-for 指令需要使用 item in items 形式的特殊语法,
items就是当前被遍历的对象或数组,item就是当前的每一项,在v-for的时候,必须设置一个:key值,保证这个key值是独一无二的
3.使用:key的时候有id即使用id,不要用index,因为在添加或者删除dom元素时,index会影响dom元素重新渲染
二、优先级:
v-for始终比v-if的优先级要高

  1. 永远不要把 v-if 和 v-for 同时用在同一个标签元素上,带来性能方面的浪费(每次渲染都会先循环再进行条件判断)简单的说他们一起使用很浪费性能,因为循环完了被隐藏了
  2. 如果非要一起使用解决方法:
    1.在外层嵌套 template (页面渲染不生成 dom 节点),在这一层进行v-if判断,根据条件进行显示隐藏,如果是显示才在内部进行v-for循环
    2.通过计算属性的方式是否缓存

71.SPA首屏加载速度慢的怎么解决?
首屏加载是用户体验最重要的一个环节,首屏加载的优化分为请求资源优化和页面渲染优化
请求资源优化:
1.减少http请求(节流,防抖)
2.压缩资源的大小(图片和代码的压缩)
3.优化资源加载时机(图片路由懒加载,按需导入UI组件)
页面渲染优化:
1.Html(把script链接放在底部,css链接放在顶部,减少dom的数量)
2.Css,js代码减少重绘和重排,动画使用transform和opcity实现动画

72.如何动态给vue的data添加一个新的属性
1.如果为对象添加少量的新属性,可以直接采用 Vue.set()
2.如果需要为新对象添加大量的新属性,则通过 Object.assign() 创建新对象
3.如果你实在不知道怎么操作时,可采取 $forceUpdate() 进行强制刷新 (不建议)
4. PS: vue3 是用过 proxy 实现数据响应式的,直接动态添加新属性仍可以实现数据响应式

73.Vue组件之间的通信方式都有哪些?
父子组件之间的通信:
注意: p a r e n t , parent, parent,children和$refs,以及provide-inject不是响应式的
父传子:子组件设置 props 属性,定义接收父组件传递过来的参数
父组件在使用子组件标签中通过:+props名来传递值
父组件在使用子组件的时候设置 ref
父组件通过设置子组件 ref 来获取数据子组件数据

子传父:子组件通过 $emit触发 自定义事件, e m i t 第 二 个 参 数 为 传 递 的 数 值 父 组 件 绑 定 监 听 器 获 取 到 子 组 件 传 递 过 来 的 参 数 子 组 件 通 过 emit 第二个参数为传递的数值 父组件绑定监听器获取到子组件传递过来的参数 子组件通过 emit第二个参数为传递的数值父组件绑定监听器获取到子组件传递过来的参数子组件通过parent获取父组件的组件数据
兄弟组件之间的通信 (3种,通过中央时间总线、通过父亲、通过vuex)
创建一个中央时间总线 EventBus
兄弟组件通过 $emit 触发自定义事件, $emit 第二个参数为传递的数值
另一个兄弟组件通过 $on 监听自定义事件

祖孙与后代组件之间的通信
在祖先组件定义 provide 属性,返回传递的值
在后代组件通过 inject 接收组件传递过来的值

非关系组件间之间的通信 Vuex
state 用来存放共享变量的地方
getter ,可以增加一个 getter 派生状态,(相当于 store 中的计算属性),用来获得共享变量的值
mutations 用来存放修改 state 的方法。
actions 也是用来存放修改state的方法,不过 action 是在 mutations 的基础上进行。常用来做一些异步操作
通过添加 namespaced: true 的方式使其成为带命名空间的模块,这样能够保证数据不被污染,且好维护

74.项目中常用的插件
① lodash - - 前端开发库
② moment - - 控制时间日期格式的
③ numeral - - 处理时间显示格式的
④ xlsx - - excel表格的操控的
⑤ wangEditor - - 富文本编辑器(还有很多不同的富文本编辑器)
⑥ Echars - - 图形化表格
⑦ eslint-config-airbnb - - 让代码提交的时候先执行一次代码,如果有报 错不让提交

76.什么是虚拟Dom?diff算法?v-for中key的作用?
虚拟Dom:
1.虚拟dom就是一个js对象,以对象的形式渲染的树形结构就是虚拟dom
2.这个虚拟dom对象通过三个参数来接收,target(当前元素div),props(标签属性),children(子元素)
3.优点:不需要操作dom
diff算法:
Diff算法是一种对比的算法。旧虚拟DOM和新虚拟DOM进行同级对比,对比新虚拟dom是哪一个虚拟节点发生改变了,找出这个虚拟节点,并只更新这个虚拟节点所对应的真实节点,而不用更新其他没有发生改变的节点,实现精准地更新真实DOM,进而提高效率。
v-for中key的作用:
key是一个唯一标识,虚拟dom的diff算法比较时候可以通过唯一的key值,能够准确的更新最新的节点.
v-for的key使用index会影响性能:
如果在元素前面新增一个node节点,在diff算法同级比较中,通过index索引去比较会让所有的节点重排,入股用唯一标识id就只是更新新增的节点

77.keep-alive的理解
一、keep-alive作用是什么?
1.keep-alive 是 vue 中的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染 DOM
2.keep-alive 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们
3.两个生命周期 activated/deactivated,用来得知当前组件是否处于活跃状态。
4.keep-alive 可以设置以下 props 属性:
include - 字符串或正则表达式。只有名称匹配的组件会被缓存
exclude - 字符串或正则表达式。任何名称匹配的组件都不会被缓存
max - 数字。最多可以缓存多少组件实例
二、keep-alive的应用场景
使用原则:当我们在某些场景下不需要让页面重新加载时我们可以使用 keepalive
当我们从 首页 –> 列表页 –> 商详页 –> 再返回 ,这时候列表页应该是需要 keep-alive
从 首页 –> 列表页 –> 商详页 –> 返回到列表页(需要缓存) –> 返回到首页(需要缓存) –> 再次进入列表页(不需要
缓存) ,这时候可以按需来控制页面的 keep-alive
在路由中设置 keepAlive 属性判断是否需要缓存
meta: {
keepAlive: true, //需要缓存
title: ‘列表页’
}

78.Vue.nextTick是什么?
Vue.nextTick一个异步执行的回调函数,因为Vue也是异步渲染dom的,nextTick就是等待当前dom数据渲染更新完毕后再去获取,此时就可以获取到更新后的dom

79.前端权限管理如何做?
前端做权限模块必须要后端提供数据,权限返回的数据结构,应该和后端沟通需要返回什么类型的数据

权限管理核心在角色上,通过给用户设置角色,然后给角色分配权限
一、前端权限的意义:
1.降低非法操作的可能性,禁用一些没有权限点击的按钮
2.减少不必要的请求,减轻服务器的压力
3.根据用户的权限匹配对应的界面,提高用户的体验
二、前端权限控制可以分为四个方面:
菜单权限(通过登录后的数据控制权限)
1.用户登录后,拿到后端返回的数据,把用户登录后的数据用this.$store.commit存储到Vuex中,(因为只有登录后才会返回数据,所以需要把数据先存储到本地sessionstorage中,再从本地获取数据保存到Vuex的state中,又因为在菜单组件中需要用到登录后的数据,所以可以引入vuex,用辅助函数mapState取出vuex中存的state数据),根据权限数据渲染出对应的菜单,点击菜单,才能看到相应的页面
2.在退出操作的时候清空本地的存储,用sessionstorage.romoveItem( )或sessionstorage.clear( ),然后用window.location.reload()刷新浏览器
路由权限(通过路由守卫判断是否携带token控制权限)
1.用户登录后获取token存储到本地session,通过router.beforeach有token就能跳到首页,没有就跳转到登录页面
2.登录后通过返回的权限数据,显示属于自己的页面,但是路由规则又是写死了的,我们需要动态的添加自己拥有权限的页面,通过后端的权限数据动态结合router的路径,实现权限和页面对应,并且去访问没有权限的页面就会跳转404页面(权限数据里面有一级权限和二级权限,分别对一级和二级权限进行遍历,让每一级权限对应到一级二级菜单的路由路径 )
按钮权限(通过后端的权限数据控制按钮权限)
1.用户虽然可以显示自己有权访问的页面,但是对一些按钮可能没有权限操作,因此,我们需要对组件中一些按钮进行控制,把用户不具备有权限的按钮进行隐藏或者禁用,
2.此时我们可以注册自定义指令来实现
directive(“permission”) 实现逻辑判断 然后在按钮中使用自定义指令进行显示隐藏和禁用
3.也可以用mixin混入来实现
接口权限(通过请求和响应拦截来控制)
1.在请求拦截器中,除了是登录页,其他的请求都要带上token,请求头字段Authorzation设置token,这样服务器才能鉴别身份
2.在响应拦截器中,如果token超时,服务器返回401,应该清空token,跳转到登录页面
2.如果发起了非权限内的请求,用户通过非法发起请求(比如控制台中关闭禁用和关闭隐藏),虽然服务器会拒绝,但是我们应该在前端直接拒绝,减少不必要请求,减小服务器压力

80.scoped原理
1.在vue的style 标签里 加上scoped属性时,他的css样式只能作用域当前的组件,这样可以让组件之间的样式私有化不被污染,
2.当我们查看dom结构的时候 可以看到加上了scoped后的组件标签 会多一个data-v-开头的动态属性,css样式上也会加上这个额外的属性选择器,
如果父组件想改子组件的css’样式 需要穿透才可以,less下用//deep sass下用::deep

81.什么是耦合、解耦
耦合 就是两个对象或者两个以上他们之间会相互作用并且相互影响,耦合度越高影响就越大 实际操作中我们应该尽量让耦合度变小,
解耦也就是字面意思 解除耦合,因为在开发中 有的模块存在依赖关系 就必然存在耦合,而且我们理论上也绝对做不到0耦合,所以只能尽量减小耦合度,以免有的代码一改动就影响其他模块

82.css sprite 精灵图
就是把多个图片合成一个图片 然后当做背景图 控制位置来显示需要的图片 ,好处就是减少http请求,并且体积更小,缺点就是如果要更换图片的话麻烦 需要整个图片重新做,或者直接添加新的图片,但是那样就会让图片越来越大,制作麻烦

83.use strict严格模式
严格模式可以让我们的代码更加规范,避免了一些潜藏的可能发生的错误,在严格模式下变量必须先声明再使用,函数的参数不能使用相同的名字,否则就会报错,禁止this指向全局,增加了一些保留字,不能对只读属性赋值

84.for in 和 for of 的区别
如果是数组的话 for in 遍历的是数组的索引,for of 遍历的数组的每一项
for of 不能遍历普通的对象,for in遍历的是对象每一项属性

85.JavaScript 中什么情况下会返回 undefined 值
1.定义一个变量 但是没有初始化值
2.定义一个变量 值就为undefined
3.一个函数没有return 一个返回值
4.一个函数 只写了个return 但是没有说明返回什么
5.函数中 访问并没有实参传入的形参
6.访问不存在的属性

86.vue3的新特性
1.Vue3比起vue2.0,实现了更小,更快,更容易维护的的渐进式框架
2.主要是结合了typescript的语法编写源码
3.把双向数据绑定响应式原理由Object.defineProperty改为基于ES6的Proxy;因为 Proxy 可以直接监听对象和数组的变化
4.还增加了一个新的组合式API—compositionAPI,比vue2的mixin更加强大,让代码更容易维护,并且不再限制 template 只有一个根节点。
5.render函数也可以返回数组了,还增加了setup() 函数,生命周期函数都写在setup里面

87.typescript的新特性
一、申明变量是用键值对语法 let list:number[]=[1,2,3]
二、typescript有11种基础类型

  1. Boolean 类型 let isDone: boolean = false;
  2. Number 类型
  3. String 类型
  4. Array 类型
    5.Enum 枚举类型 (数字枚举、字符串枚举、异构枚举)
    6.Any 类型 (任何类型都可以归位any类型,也称全局超级类型 )
    7.Unknown 类型 (另一种顶级类型)
    8.viod类型 ( 声明一个void 类型的变量没有什么作用,因为它的值只为 undefined 或 null)
  5. Tuple 元组类型 (类似与数组)
    10.Null 和 Undefined 类型
    11.Never 类型 (表示的是那些永不存在的值的类型)
    三、typescript新增的断言
    “尖括号” 语法:
    let someValue: any = “this is a string”;
    let strLength: number = (someValue).length;
    as 语法:
    let someValue: any = “this is a string”;
    let strLength: number = (someValue as string).length;
    四、类型守卫(保护)
    (类型保护是可执行运行时检查的一种表达式,用于确保该类型在一定的范围内。换句话说,类型保护可以保证一个字符串是一个字符串,尽管它的值也可以是一个数值。类型保护与特性检测并不是完全不同,其主要思想是尝试检测属性、方法或原型,以确定如何处理值。目前主要有四种的方式来实现类型保护)
    in 关键字 typeof 关键字 instanceof 关键字
    五、TypeScript 中的函数

88.增删改查中设置id唯一值,取最大值
Var ID=Math.Max(…this.lists.map(item=>item.id))+1

89.webpack是什么?webpack是一个静态模块打包工具,可以把前端所有的资源文件打包成压缩后的静态资源模块!核心概念有entry入口、output出口、module模块、loader模块转换器、plugin、拓展插件
1.webpack的作用
· 代码转换:TypeScript 编译成 JavaScript、SCSS 编译成 CSS 。
· 文件优化:压缩 JavaScript、CSS、HTML 代码,压缩合并图片等。
· 代码分割:提取多个页面的公共代码、提取首屏不需要执行部分的代码让其异步加载。
· 模块合并:在采用模块化的项目里会有很多个模块和文件,需要构建功能把模块分类合并成一个文件。
· 自动刷新:监听本地源代码的变化,自动重新构建、刷新浏览器。
· 代码校验:在代码被提交到仓库前需要校验代码是否符合规范,以及单元测试是否通过。
· 自动发布:更新完代码后,自动构建出线上发布代码并传输给发布系统。
2.webpack核心概念
Entry:入口,webpack执行构建的第一步将从Entry开始,可抽象理解为输入
Module:模块,在webpacl中一切皆为模块,一个模块对应一个文件,webpack会从配置的Entry开始递归找出所有依赖的模块
Chunk:代码块,一个chunk由多个模块组合而成,用于将代码合并和分割
Loader:模块转换器,用于把模块原内容按照需求转换为需要的新内容
Plugin:扩展插件,在webpack构建流程中的特定时机注入扩展逻辑来改变构建结果和想要做的事情
Output:输入结果,在webpack经过一系列处理并得到最终想要的代码然后输出

89.Vue中13个常用的指令
1、v-model 多用于表单元素实现双向数据绑定(同 angular 中的 ng-model)
2、v-for 格式: v-for=“字段名 in(of) 数组 json” 循环数组或 json(同 angular 的 ngrepeat),需要注意从 vue2 开始取消了$index
3、v-show 显示内容 (同 angular 中的 ng-show)
4、v-hide 隐藏内容(同 angular 中的 ng-hide)
5、v-if 显示与隐藏 (dom 元素的删除添加 同 angular 中的 ng-if 默认值为 false)v-else-if 必须和 v-if 连用 v-else 必须和 v-if 连用 不能单独使用 否则报错,模板编译错误
6、v-bind 动态绑定 作用: 及时对页面的数据进行更改
7、v-on:click 给标签绑定函数,可以缩写为@,例如绑定一个点击函数 函数必须写在 methods 里面
8、v-text 解析文本
9、v-html 解析 html 标签
10、v-bind:class 三种绑定方法 1、对象型 ‘{red:isred}’ 2、三元型’isred?“red”:“blue”’ 3、数组型 ‘[{red:“isred”},{blue:“isblue”}]’
11、v-once 进入页面时 只渲染一次 不在进行渲染
12、v-cloak 防止闪烁
13、v-pre 把标签内部的元素原位输出
Vue 修饰符有哪些
常用的事件修饰符
.stop:阻止冒泡
.prevent:阻止默认行为
.self:仅绑定元素自身触发
.once: 2.1.4 新增,只触发一次
passive: 2.3.0 新增,滚动事件的默认行为 (即滚动行为) 将会立即触发,不能和.prevent 一起使用
.sync 修饰符
vue中使用原生的事件,在原生事件上加上.native 修饰符

90. 路由钩子函数
1.全局守卫钩子函数:beforeEach(to,from,next),无论访问哪一个路径,都会触发全局的钩子函数,位置是调用router的方法
2.路由守卫(独享)钩子函数:beforeEnter(to,from,next)写在路由配置中,只有访问到这个路径,才能触发钩子函数
3.组件守卫路由钩子函数:beforeRoterEnter(to,from,next)写在组件中,访问路径,即将渲染组件的时候触发的、

91.Vue 的父子组件生命周期钩子函数执行顺序
created初始化阶段:先父后子
mounted渲染阶段:先子后父
update更新阶段:父 beforeUpdate->子 beforeUpdate-> 子 updated->父 updated
destroy销毁阶段:父 beforeDestroy->子 beforeDestroy->子 destroyed->父 destroyed

92.使用Vuex 页面刷新数据丢失怎么解决
1.存储state数据时先存本地,再获取
2.推荐使用 vuex-persist 插件,它就是为 Vuex 持久化存储而生的一个插件。不需要你手动存取 storage ,而是直接将状态保存至 cookie 或者 localStorage 中

93.使用过 Vue SSR 吗?说说 SSR
SSR 也就是服务端渲染,也就是将 Vue 在客户端把标签渲染成 HTML 的工作放在服务端完成,然后再把 html 直接返回给客户端。

94.vue 中使用了哪些设计模式
1.工厂模式 - 传入参数即可创建实例虚拟 DOM 根据参数的不同返回基础标签的 Vnode 和组件 Vnode
2.单例模式 - 整个程序有且仅有一个实例vuex 和 vue-router 的插件注册方法 install 判断如果系统存在实例就直接返回掉
3.发布-订阅模式 (vue 事件绑定机制)
4.观察者模式 (响应式数据原理)

95.vue中的优化
1.防止内部泄漏,组件销毁后把全局变量和事件销毁
2.图片懒加载
3.路由懒加载
4.第三方插件的按需引入
5.适当采用 keep-alive 缓存组件
6.防抖、节流运用
7.v-for 遍历必须加 key,key 最好是 id 值,且避免同时使用 v-if
8.v-if 和 v-show 区分使用场景
96.vue3搭建项目需要的技术栈

2021最前端最常见的面试题相关推荐

  1. 2021年Vue最常见的面试题以及答案(面试必过)

    Vue常见面试题 Vue的优点 说说你对SPA单页面的理解,它的优缺点分别是什么? SPA首屏加载速度慢的怎么解决? Vue初始化过程中(new Vue(options))都做了什么? 对MVVM的理 ...

  2. 前端一面常见vue面试题汇总

    说说你对 proxy 的理解,Proxy 相比于 defineProperty 的优势 Object.defineProperty() 的问题主要有三个: 不能监听数组的变化 :无法监控到数组下标的变 ...

  3. 前端不常见25k+面试题(持续更新)

    这一套面试题可能和网上看到的都不太一样,如果你都能答出来,那你就是25k+的水平了 1.苹果手机字体的锯齿怎么实现平滑 -webkit-font-smoothing: subpixel-antiali ...

  4. 前端一些常见的面试题

    前端面试题 Happy coding. new的原理 function Foo (name, age) {this.name = name;this.age = age;this.class = 'c ...

  5. 2021年Javascript最常见的面试题以及答案

    Js面试题以及答案(建议收藏,面试必过!) 从输入 URL 到页面展示,这中间发生了什么? JavaScript的数据类型及其检测? typeof 和 instanceof 的区别? 对栈和堆内存有了 ...

  6. 前端最常见的面试题整理

    自我简介 你好,面试官,我叫XX,有两年的开发经验,来应聘前端开发工程师这一岗位,上一家公司是XXX时代科技有限公司,期间主要负责pc端网站的开发,还有微信小程序和app的维护,开发的技术栈主要就是v ...

  7. 前端的常见的面试试题

    Javascript有哪些打开一个页面的方式? 1.超链接<a href="http://www.100sucai.com/" title="100素材网" ...

  8. Web前端人员如何面试?常见vue面试题有哪些?

    Web前端人员如何面试?常见vue面试题有哪些?vue是一套用于构建用户界面的渐进式JavaScript框架,也是初创项目的首选前端框架.很多企业在招聘前端工程师时都会考察其对vue的了解,接下来小编 ...

  9. 划重点,2021 常见的面试题和八股文都为大家总结出来了

    今年的秋招基本已经进入大规模的开奖季了,很多小伙伴收获不错,拿到了心仪的 offer. 各大论坛和社区里也看见不少小伙伴慷慨地分享了常见的面试题和八股文,为此咱这里也统一做一次大整理和大归类,这也算是 ...

最新文章

  1. 一个可提供html5制作服务的网站
  2. 50位青年科学家获颁1.5亿大奖!3位大咖这样寄语
  3. 百度2011实习生招聘笔试题
  4. 8、MySQL表锁、行锁和页锁
  5. 04.内置analyzer和analyze-API使用
  6. VTK:VTK嵌入MFC成功
  7. 【python基础】——数据类型(列表、字典、集合)
  8. python重定向_Python接口自动化(十)重定向(Location)
  9. vscode如何关闭Pylint警告或错误提示
  10. Chapter 04-Using Conversion Functions and Conditional Expressions-Conditional Expressions
  11. d2crub学习2 算合计
  12. WinCC 在线变量绘制趋势图(自定义内部变量-随机数据)
  13. 服务器抓不到mrcp协议,mrcp与一句话识别
  14. 【QCM2150】WFA 11ac 4.2.43测试失败及解决方案
  15. 电话号码的字母组合(Java)
  16. 目标-过程-结果经验分享及OKR工作法
  17. 微信小程序的复制功能
  18. java基础应用程序超市收银_超市收银程序(JAVA课程设计 2011)
  19. 微信公众号开发——模板消息
  20. js判断字符超长度中间用...替换

热门文章

  1. mongodb 面试题
  2. python3.x之print()不换行解决方案
  3. 线性回归-吴恩达-机器学习课后作业
  4. python中object的用法_Python object()用法及代码示例
  5. Centos查看端口占用情况和开启端口命令
  6. windows 如何查看端口占用情况?
  7. Python 递归 深入理解递归 Python递归剖析,绝对让你看懂!
  8. ToneSpotVoice 效果器 简单功能讲解
  9. 杰理之MIDI 乐谱解码运行步骤【篇】
  10. “未来工厂”——数字化车间