1. token拷贝到别人电脑上,禁止授权:
颁发Token时记录访问者ip ,当ip 发生变化时,Token作废。
2.em和rem是相对长度单位
1.em的值并不是固定的;
2.em会继承父级元素的字体大小。
3.vuex值特别多的时候,第一次加载慢怎么处理?
1.去掉编译文件中的map文件。 路由懒加载:可以将页面中的资源划分为多份,减少第一时间的消耗。
2.使用CDN减少代码体积加快请求速度。
4. 说说WebSocket:
WebSocket是一个持久化协议,因为HTTP 不支持持久链接,他是对http 协议的一种补充。
优点:1.服务端可以主动推送信息给客户端,只需要经过一次http请求就可以不间断的传送信息。2.解决客服处理速度过慢的问题。
缺点:兼容性差。
5.什么是回流 ?
当render tree中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建。这就称为回流(reflow)。
每个页面至少需要一次回流,就是在页面第一次加载的时候,这时候是一定会发生回流的,因为要构建render tree。
在回流的时候,浏览器会使渲染树中受到影响的部分失效,并重新构造这部分渲染树,完成回流后,浏览器会重新绘制受影响的部分到屏幕中,该过程成为重绘。
区别: 回流必将引起重绘,而重绘不一定会引起回流。
减少重绘和回流的办法: 使用translate新属性替代top等方向值。 避免频繁使用style而是采用class。
6.谈谈垃圾回收机制:
垃圾回收机制: 当一个变量在内存中失去引用,js会通过特殊的算法将其回收,并释放内存。
标记阶段:垃圾回收器,从根对象开始遍历,访问到的每一个对象都会被标示为可到达对象。
清除阶段:垃圾回收器在对内存当中进行线性遍历,如果发现该对象没有被标记为可到达对象,那么就会被垃圾回收机制回收。
7.函数的防抖和节流?
函数的防抖:将多次触发变成最后一次触发。
函数的截流:将多次执行变成每隔一个时间去执行。
8.DOM操作
怎样添加、移除、移动、复制、创建和查找节点。
(1)创建新节点
createDocumentFragment() //创建一个DOM片段
createElement() //创建一个具体的元素
createTextNode() //创建一个文本节点
(2)添加、移除、替换、插入、修改
appendChild()
removeChild()
replaceChild()
insertBefore()
setAttribute()
(3)查找
getElementsByTagName() //通过标签名称
getElementsByName() //通过元素的Name属性的值
getElementById() //通过元素Id,唯一性
9.捕获和冒泡
捕获:就是从根元素开始向目标元素递进的一个关系;从上而下
冒泡:是从目标元素开始向根元素冒泡的过程;想象一下水里的泡泡从下而上。
10.script标签如何实现异步加载?
defer:等到整个页面在内存中华正常渲染结束(DOM结构完全生成,以及其他脚本执行完成),才会执行;
async是一旦下载完成,渲染就会中断,执行这个脚本之后,再继续渲染。
11.call、apply区别
相同点:都是重定向this指针的方法。
不同点:call和apply的第二个参数不相同,call是若干个参数的列表,apply是一个数组。
12.http和https区别
http:80端口 , 无需申请证书, 超文本传输协议 , 快
https:443端口,需要申请证书,ssl加密协议 ,慢(因为会有一个ssl包需要传输)
13.如何实现图片懒加载
当访问一个页面的时候,先把img元素或是其他元素的背景图片路径替换成一张大小为1*1px图片的路径(这样就只需请求一次),只有当图片出现在浏览器的可视区域内时,才设置图片真正的路径,让图片显示出来。这就是图片懒加载。 通常可以借助IntersectionObserver API。
14.常见的网站漏洞有哪些?
有跨站脚本攻击(XSS)
跨站请求伪造(CSRF)
点击劫持
SQL注入
DDOS攻击
DNS劫持
15.js的作用域和作用域链 作用域:
全局作用域: 最外层函数定义的变量拥有全局作用域,即对任何内部函数来说,都是可以访问的。
局部作用域: 和全局作用域相反,局部作用域一般只在固定的代码片段内可访问到,而对于函数外部是无法访问的,最常见的例如函数内部。
函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量!
作用域链:
一层一层的向上查找,这么一个查找过程形成的链条就叫做作用域链。
16.什么是盒子模型
网页中的任何一个标签都相当于是一个盒子模型,而所有的盒子模型都存在五个必要的属性:width,height,padding,border,margin.
17.深入浅出之vue-cli混入(mixins)的理解和使用
省好多代码,而且方便维护。
18.箭头函数和普通函数的区别:
箭头函数是匿名函数,不能作为构造函数,不能使用new ,
箭头函数的 this 永远指向其上下文的this,
任何方法都改变不了其指向。
19.vue的$nextTick用过吗
可以处理异步,在下次 DOM更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。(官网解释)
解决的问题:有些时候在改变数据后立即要对dom进行操作,此时获取到的dom仍是获取到的是数据刷新前的dom,无法满足需要,这个时候就用到了$nextTick。
20.vue的单项数据流和双向数据流绑定是什么意思?
单项数据流:是指数据是单向的,父组件的数据传递给子组件,只能单项绑定,不可以在子组件修改父组件的数据。
双向数据绑定:是指数据和页面进行双向绑定,相互影响。
21.栈和堆的区别
堆(数据结构):堆可以被看成是一棵树,如:堆排序; 栈(数据结构):一种先进后出的数据结构。
22.事件委托
事件委托就是利用的DOM事件的事件捕获阶段。把具体dom上发生的事件,委托给更大范围的dom去处理。比如li列表的事情交给ul做。
23. 浏览器是如何渲染页面的 渲染的流程如下:
1.解析HTML文件,创建DOM树。 自上而下,遇到任何样式(link、style)与脚本(script)都会阻塞(外部样式不阻塞后续外部脚本的加载)。
2.解析CSS,构建渲染树。优先级:浏览器默认设置<用户设置<外部样式<内联样式3.将CSS与DOM合并,构建渲染树(Render Tree)
3.页面的重绘(repaint)和重排(reflow)
24. xml和json的区别 ·
JSON相对于XML来讲,数据的体积小,传递的速度更快些 ·
JSON与JavaScript的交互更加方便,更容易解析处理,更好的数据交互
XML对数据描述性比较好
JSON的速度要远远快于XML
25.什么是暂时性死区?
暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。
26. svg和canvas区别?
SVG 是一种使用 XML 描述 2D 图形的语言。
Canvas 通过 JavaScript 来绘制2D 图形。
SVG 基于 XML,这意味着 SVG DOM 中的每个元素都是可用的。您可以为某个元素附加 JavaScript事件处理器。
在 SVG 中,每个被绘制的图形均被视为对象。如果 SVG 对象的属性发生变化,那么浏览器能够自动重现图形。
Canvas 是逐像素进行渲染的。在 canvas中,一旦图形被绘制完成,它就不会继续得到浏览器的关注。如果其位置发生变化,那么整个场景也需要重新绘制,包括任何或许已被图形覆盖的对象。
27. h5的新特性
(1)语义标签 (2)增强型表单 (3)视频和音频 (4)Canvas绘图
28.css3新特性
css3的新选择器 文本的新属性 边框(边框圆角、边框图片) 背景的缩放 颜色渐变 动画、旋转 多列布局 flex布局
29.ajax的底层原理?
Ajax的最大特点是:异步访问、局部刷新。核心是:XML。 Ajax的关键技术:
1.使用css搭建界面样式,负责页面的排版和美工
2.使用DOM进行动态显示和交互,对页面进行局部修改
3.使用XMLHttpRequest异步获取数据
4.使用JavaScript将所有的元素绑在一起 第一步:创建XMLHttpRequest对象 第二步:建立到服务器的连接 第三步:指定回调函数
30.H5新增标签
header头部
section中间区块
footer尾页
aside其他的内容
datalist定义选项列表
audio音频
video视频
embed媒体内插入内容
nav定义导航链接
article独立的内容
31. 居中的方式有哪些?
垂直居中: align-items:center
水平居中: justify-content:center
左对齐:justify-content:flex-start
右对齐:justify-content:flex-end
两端对齐:justify-content:space-between
32.深入理解promise
1、主要用于异步计算
2、可以将异步操作队列化,按照期望的顺序执行
promise有三个状态: 1、pending[待定]初始状态 2、fulfilled[实现]操作成功3、rejected[被否决]操作失败
优点:Promise 实现了链式调用,也很好地解决了回调地狱的问题
缺点: 1.一旦执行无法取消。2.错误需要通过回调函数捕获 3.当处于 Pending 状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。
Promise.prototype.then方法:就是实现链式操作,默认有resolve 和 reject参数,成功和失败的参数,返回的是一个新的 Promise 对象
Promise.prototype.catch方法:捕捉错误的回调函数
Promise.all()执行多个,一个失败都失败,返回第一个失败的错误
Promise.race() 执行多个,返回的是率先执行的那条数据的状态
Promise.reject(reason): 返回一个状态为失败的Promise对象,并将给定的失败信息传递给对应的处理方法
Promise.resolve(value):可以将一个对象转化为promise对象。
33.async 及 await
一个函数如果加上 async ,那么该函数就会返回一个 Promise await 只能配套 async使用 ,
async 和 await 可以说是异步终极解决方案了,相比直接使用 Promise 来说,优势在于处理 then 的调用链,能够更清晰准确的写出代码 也能优雅地解决回调地狱问题。
缺点,因为 await将异步代码改造成了同步代码,如果多个异步代码没有依赖性却使用了 await 会导致性能上的降低。
await 内部实现了generator,其实 await 就是 generator 加上 Promise 的语法糖,且内部实现了自动执行generator。
34.generator和function
是一个可以暂停的函数,yield表达式是暂停执行,而next方法可以恢复执行。
用generator函数,返回一个遍历器对象,代表generator函数的内部指针,
每次调用遍历器对象next方法,会返回一个有value和done两个属性的对象,value是值,是yield表达式后边表达式的值,done是一个布尔值,表示遍历是否结束
35.class类、 构造函数
class类,默认有constructor方法,new之后,自动调用该方法,以前写个构造函数,会在类的prototype上加,现在类有constructor和其他方法,相当于写在类的原型上,也就相当于写在了构造函数的prototype上
区别: (1)不存在变量提升
(2)方法默认是不可枚举的,class所有方法没有原型对象prototype也没有构造器不能用new来调用;
(3)、class在语法上更贴近面向对象的写法。
(4)、class实现继承更加易读易理解。
36.深拷贝和浅拷贝
• 浅拷贝(shallowCopy)只是增加了一个指针指向已存在的内存地址,如果原地址发生改变,那么浅复制出来的对象也会相应的改变。
• 深拷贝(deepCopy)是增加指针,申请一个新的内存,使这个增加的指针指向这个新的内存。原地址发生改变也不影响。
37.宏任务和微任务:
宏任务 一般分为定时器那种,script 微任务 一般是promise这种 不同类型的任务会进去对应的事件循环。
执行一个宏任务,执行过程中如果遇到微任务,就将它添加到微任务的任务队列中,宏任务执行完毕后,立即执行当前微任务队列中的所有微任务(依次执行),再开始下一个宏任务(从事件队列中获取)
38.继承
class中extends继承,通过extends会继承所有的类和方法,子类必须在constructor方法中调用super方法,否则新建实例时会报错。这是因为子类自己的this对象,必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后再对其进行加工,加上子类自己的实例属性和方法,如果不调用super方法,子类就得不到this对象。
39.父子组件传值
1.props.
e
m
i
t
在
父
组
件
中
绑
定
变
量
,
在
子
组
建
定
义
p
r
o
p
s
来
接
收
父
组
件
传
递
的
变
量
在
子
组
件
中
绑
定
事
件
,
触
发
的
时
候
用
emit 在父组件中绑定变量,在子组建定义props 来接收父组件传递的变量 在子组件中绑定事件,触发的时候用
emit在父组件中绑定变量,在子组建定义props来接收父组件传递的变量在子组件中绑定事件,触发的时候用emit触发父组件中的函数,并将组件中的变量作为参数传递。
2.在子组件定义ref,通过this.$refs获取到dom 元素和子组件实例
3.依赖注入 父组件定义provide,提供要传递的数据 子组件使用inject来接收
40.keepalive
keep-alive是一个抽象组件:keep-alive用于保存组件的渲染状态。它自身不会渲染一个DOM元素,也不会出现在父组件链中;能够节省性能消耗,避免一个组件频繁重新渲染,节省开支
include定义缓存白名单,keep-alive会缓存命中的组件;exclude定义缓存黑名单,被命中的组件将不会被缓存;max定义缓存组件上限,超出上限使用LRU的策略置换缓存数据。
被缓存组件的钩子函数只会执行一次,只有activated和deactivated 这两个钩子函数会再次执行
41.webpack的vue.config.js配置
1、核心概念 (1)entry:一个可执行模块或者库的入口。
(2)chunk:多个文件组成一个代码块。可以将可执行的模块和他所依赖的模块组合成一个chunk,这是打包。
(3)loader:文件转换器。例如把es6转为es5,scss转为css等
(4)plugin:扩展webpack功能的插件。在webpack构建的生命周期节点上加入扩展hook,添加功能。
2、webpack构建流程(原理) 从启动构建到输出结果一系列过程:
(1)初始化参数:解析webpack配置参数,合并shell传入和webpack.config.js文件配置的参数,形成最后的配置结果。
(2)开始编译:上一步得到的参数初始化compiler对象,注册所有配置的插件,插件监听webpack构建生命周期的事件节点,做出相应的反应,执行对象的
run 方法开始执行编译。 (3)确定入口:从配置的entry入口,开始解析文件构建AST语法树,找出依赖,递归下去。
(4)编译模块:递归中根据文件类型和loader配置,调用所有配置的loader对文件进行转换,再找出该模块依赖的模块,再递归本步骤直到所有入口依赖的文件都经过了本步骤的处理。
(5)完成模块编译并输出:递归完事后,得到每个文件结果,包含每个模块以及他们之间的依赖关系,根据entry配置生成代码块chunk。
(6)输出完成:输出所有的chunk到文件系统。
注意:在构建生命周期中有一系列插件在做合适的时机做合适事情,比如UglifyPlugin会在loader转换递归完对结果使用UglifyJs压缩覆盖
42.Axios
Axios是一个基于 promise 的 HTTP 库,用于向后台发起请求的 。
特点:
支持浏览器和node.js
支持promise
能拦截请求和响应
能转换请求和响应数据
能取消请求
自动转换JSON数据
浏览器支持防止CSRF(跨站请求伪造)
axios的底层原理 axios 原理还是属于 XMLHttpRequest, 加一个promise对象来对结果进行处理
43.this指向
(1)全局函数 全局环境中this指向window
(2)方法调用:this指向调用该方法的对象
(3)构造函数调用:this指向新创建的实例对象
(4)call和apply允许改变this指向,通常指向函数中指定的参数对象;
(5)箭头函数的调用:由于没有this对象,所以指向外层的this
(6)在函数中,在严格模式下,this是未定义的(undefined)
(7)在事件中,this 表示接收事件的元素;
44.前端性能优化有哪些方面:
(1)网络层面:减少HTTP请求,合并css、js文件,雪碧图(css、sprite)的使用、使用base64表示简单的图片(空白图) 减小资源体积:gzip压缩、js、css、图片压缩,缓存应用:DNS缓存,CDN部署与缓存、http缓存。
(2)渲染和操作DOM方面:css文件放在头部、js文件放在尾部或者异步,尽量避免内联样式,尽量避免在document上直接频繁操作dom,尽量使用css动画
使用calssName代替大量的内联样式的修改、使用事件代理;减少标签选择器的使用;
(3)数据交互层面:图片预加载、懒加载;异步请求的优化:使用json数据格式进行交互,部分常用数据缓存;大量数据运算时候使用webWorker;
45.vue-router
vue-router的2种模式以及原理 mode参数决定类型;可选值: “hash” | “history” | “abstract”(Node.js 环境)
(1)hash模式:hash模式背后的原理是onhashchange事件,可以在window对象上监听这个事件,改变 hash,不会重新加载页面 。
(2)history模式: history.pushState API 来完成 URL 跳转而无须重新加载页面。
路由守卫是路由拦截,我们可以通过路由拦截,来判断用户是否登录,该页面用户是否有权限浏览,需要结合meta来实现。
根据后台返回的用户权限动态添加路由规则,这样的话每个用户的路由规则都是不同的。
全局前置守卫 router.beforeEach
全局解析守卫 router.beforeResolve
全局后置钩子router.afterEach
路由独享钩子:beforeEnter
通过 vm.
r
o
u
t
e
r
.
p
u
s
h
或
者
v
m
.
router.push 或者 vm.
router.push或者vm.router.replace 进行 页面跳转。
怎么定义 vue-router 的动态路由以及如何获取传过来的动态参数? 在 router 目录下的 index.js 文件中,对 path 属性加上/:id。使用 router 对象的 params.id可获取传来的参数。
46.vue响应式数据的原理
采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter, getter。
默认Vue 在初始化数据时,会给data 中的属性使用Object.defineProperty 重新定义所有属性,
当页面到对应属性时,会进行依赖收集(收集当前组件中的watcher ),如果属性发生变化会通知相关依赖进行更新操作;
47. 闭包的概念:
闭包就是能读取其他函数内部变量的函数。
闭包特性,函数嵌套函数,在函数内部可以引用外部的参数和变量,参数和变量不会被垃圾回收机制回收。
优点:
1. 避免全局变量的污染
2. 可以读取函数内部的变量
缺点:
1. 内存泄露(消耗)
2. 增加内存使用量
处理内存泄露: 在生命周期beforDestroy销毁前作处理。
48. link和import区别:
页面加载时,link会同时被加载 ;
@import引用的css会等到页面被加载完成之后再加载,只能加载css。
link是没有任何兼容问题的。
link支持使用js去控制dom改变样式
49.ES6都用到哪些
语法糖(箭头函数,类的定义,继承),以及一些新的扩展(数组,字符串,对象,方法等),对作用域的重新定义,以及异步编程的解决方案(promise,async,await)、数组的解构赋值
50.原型和原型链:
原型: ①所有引用类型都有一个__proto__(隐式原型)属性,属性值是一个普通的对象
②所有函数都有一个prototype(原型)属性,属性值是一个普通的对象
③所有引用类型的__proto__属性指向它构造函数的prototype
原型链:
当访问一个对象的某个属性时,会先在这个对象本身属性上查找,如果没有找到,则会去它的隐式原型上查找,如果还没有找到就会在构造函数的prototype的__proto__中查找,这样一层一层向上查找就会形成一个链式结构,我们称为原型链。
51.computer、watch区别及什么需要用到watch及缺点 ?
computed 是计算属性,依赖其他属性计算值,并且 computed的值有缓存,只有当计算值变化才会返回内容。
watch 监听到值的变化就会执行回调,在回调中可以进行一些逻辑操作。
所以一般来说需要依赖别的属性来动态获得值的时候可以使用 computed,对于监听到值的变化需要做一些复杂业务逻辑的情况可以使用watch。
52.React,Angular 和 Vue 的比较
组件 React 和 Vue都擅长处理组件:小型的无状态的函数接收输入和返回元素作为输出。
React 专注于使用 Javascript ES6。
Vue 使用Javascript ES5 或 ES6。
Angular 依赖于 TypeScript。
1. 上手难度 Vue < react < angular
2. 使用场景 Vue React 覆盖中小型,大型项目。 angular 一般用于大型(因为比较厚重)。 优缺点
3. 渲染性能 Vue> react >angular
53.继承的方法有哪些?
原型链继承 、构造函数继承、 寄生继承 、组合继承、 寄生组合继承 、原型式继承
54.说说有几种类型的DOM节点
DOM节点类型有:Document节点,整个文档是一个文档节点;Element节点,每个HTML标签是一个元素节点;Attribute节点,每一个HTML属性是一个属性节点;Text节点,包含在HTML元素中的文本是文本节点。
55. 为什么不建议在JavaScript中使用innerHTML?
innerHTML内容每次刷新,因此很慢。
在innerHTML中没有验证的余地,因此,更容易在文档中插入错误代码,从而使网页不稳定。
56. 说说JavaScript的同源策略
同源策略的目的是为了防止某个文档或脚本从多个不同源装载,同源策略是指,协议,域名,端口相同。同源策略是一种安全协议,指一段脚本只能读取来自同一来源的窗口和文档的属性。
说一下为啥要有同源限制?
有同源限制可以放置黑客盗取信息。
57. document.write和innerHTML的区别
document.write会重绘整个页面
innerHTML可以重绘页面的一部分
58. 组件中为什么data是一个函数?
因为组件是需要被复用的,所以必须是一个函数,如果是一个对象,作用域没有分开,子组件的data属性值会相互影响。是一个函数的话那么每个实例可以维护一份被返回对象的独立的拷贝,组件之间的data 属性值不会互相影响。
59.为何 v-for 要用 key?
必须要用 key, 而且不能用 index 和 random,
key是vue中vnode的唯一标记,通过这个key,我们的diff操作可以更准确,更快速在 diff 算法中用 tag 和 key来判断,是否是sameNode可以减少渲染次数,提高渲染性能。