VUE面试题

 

1. Vue实现双向绑定的原理

vue实现数据双向绑定主要是:采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应监听回调。当把一个普通 Javascript 对象传给 Vue 实例来作为它的 data 选项时,Vue 将遍历它的属性,用 Object.defineProperty 将它们转为 getter/setter。用户看不到 getter/setter,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。

vue的数据双向绑定 将MVVM作为数据绑定的入口,整合Observer,Compile和Watcher三者,通过Observer来监听自己的model的数据变化,通过Compile来解析编译模板指令(vue中是用来解析 {{}}),最终利用watcher搭起observer和Compile之间的通信桥梁,达到数据变化 —>视图更新;视图交互变化(input)—>数据model变更双向绑定效果。

2.Vue组件间的参数传递

1.父组件与子组件传值
父组件传给子组件:子组件通过props方法接受数据;
子组件传给父组件:$emit方法传递参数
2.非父子组件间的数据传递,兄弟组件传值
eventBus,就是创建一个事件中心,相当于中转站,可以用它来传递事件和接收事件。项目比较小时,用这个比较合适。(虽然也有不少人推荐直接用VUEX,具体来说看需求咯。技术只是手段,目的达到才是王道。)

3. Vue路由的实现:hash模式和history模式

hash模式:在浏览器中符号“#”,#以及#后面的字符称之为hash,用window.location.hash读取;
特点:hash虽然在URL中,但不被包括在HTTP请求中;用来指导浏览器动作,对服务端安全无用,hash不会重加载页面。
hash 模式下,仅 hash 符号之前的内容会被包含在请求中,如 http://www.xxx.com,因此对于后端来说,即使没有做到对路由的全覆盖,也不会返回 404 错误。

history模式:history采用HTML5的新特性;且提供了两个新方法:pushState(),replaceState()可以对浏览器历史记录栈进行修改,以及popState事件的监听到状态变更。
history 模式下,前端的 URL 必须和实际向后端发起请求的 URL 一致,如 http://www.xxx.com/items/id。后端如果缺少对 /items/id 的路由处理,将返回 404 错误。Vue-Router 官网里如此描述:“不过这种模式要玩好,还需要后台配置支持……所以呢,你要在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面,这个页面就是你 app 依赖的页面。

4. Vue路由的钩子函数

首页可以控制导航跳转,beforeEach,afterEach等,一般用于页面title的修改。一些需要登录才能调整页面的重定向功能。

beforeEach主要有3个参数to,from,next:

to:route即将进入的目标路由对象,

from:route当前导航正要离开的路由

next:function一定要调用该方法resolve这个钩子。执行效果依赖next方法的调用参数。可以控制网页的跳转

5. Vue的生命周期

beforeCreate(创建前) 在数据观测和初始化事件还未开始
created(创建后) 完成数据观测,属性和方法的运算,初始化事件,$el属性还没有显示出来
beforeMount(载入前) 在挂载开始之前被调用,相关的render函数首次被调用。实例已完成以下的配置:编译模板,把data里面的数据和模板生成html。注意此时还没有挂载html到页面上。
mounted(载入后) 在el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用。实例已完成以下的配置:用上面编译好的html内容替换el属性指向的DOM对象。完成模板中的html渲染到html页面中。此过程中进行ajax交互。
beforeUpdate(更新前) 在数据更新之前调用,发生在虚拟DOM重新渲染和打补丁之前。可以在该钩子中进一步地更改状态,不会触发附加的重渲染过程。
updated(更新后) 在由于数据更改导致的虚拟DOM重新渲染和打补丁之后调用。调用时,组件DOM已经更新,所以可以执行依赖于DOM的操作。然而在大多数情况下,应该避免在此期间更改状态,因为这可能会导致更新无限循环。该钩子在服务器端渲染期间不被调用。
beforeDestroy(销毁前) 在实例销毁之前调用。实例仍然完全可用。
destroyed(销毁后) 在实例销毁之后调用。调用后,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用。
1.什么是vue生命周期?
答: Vue 实例从创建到销毁的过程,就是生命周期。从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、销毁等一系列过程,称之为 Vue 的生命周期。

2.vue生命周期的作用是什么?
答:它的生命周期中有多个事件钩子,让我们在控制整个Vue实例的过程时更容易形成好的逻辑。

3.vue生命周期总共有几个阶段?
答:它可以总共分为8个阶段:创建前/后, 载入前/后,更新前/后,销毁前/销毁后。

4.第一次页面加载会触发哪几个钩子?
答:会触发 下面这几个beforeCreate, created, beforeMount, mounted 。

5.DOM 渲染在 哪个周期中就已经完成?
答:DOM 渲染在 mounted 中就已经完成了。

6. Vuex是什么?怎么使用?哪种功能场景使用它?

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。每一个 Vuex 应用的核心就是 store(仓库)。“store” 基本上就是一个容器,它包含着你的应用中大部分的状态 ( state )。

在main.js引入store,注入。新建了一个目录store,….. export 。
场景有:单页应用中,组件之间的状态、音乐播放、登录状态、加入购物车

state : Vuex 使用单一状态树,即每个应用将仅仅包含一个store 实例,但单一状态树和模块化并不冲突。存放的数据状态,不可以直接修改里面的数据。

mutations : 修改Vuex 的 store 中的状态或数据。

getters:类似vue的计算属性,主要用来过滤一些数据。

action :可以理解为通过将mutations里面处里数据的方法变成可异步的处理数据的方法,简单的说就是异步操作数据。view 层通过 store.dispath 来分发 action。

modules:项目特别复杂的时候,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。

7. Vue 中key有什么作用?

当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。key的作用主要是为了高效的更新虚拟DOM。

8. Vue路由跳转有哪几种?

1.router-link

不带参数
<router-link :to="{name:'home'}">
<router-link :to="{path:'/home'}"> //name,path都行, 建议用name
// 注意:router-link中链接如果是'/'开始就是从根路由开始,如果开始不带'/',则从当前路由开始。
带参数
<router-link :to="{name:'home', params: {id:1}}">

2.this.$router.push() (函数里面调用)

不带参数
this.$router.push('/home')
this.$router.push({name:'home'})
this.$router.push({path:'/home'})
query传参
this.$router.push({name:'home',query: {id:'1'}})
this.$router.push({path:'/home',query: {id:'1'}})

9. 怎样理解 Vue 的单向数据流?

所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。
这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。
额外的,每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的值。
这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。
子组件想修改时,只能通过 $emit 派发一个自定义事件,父组件接收到后,由父组件修改。

10. 深拷贝和浅拷贝的区别

首先深复制和浅复制只针对像 Object, Array 这样的复杂对象的。简单来说,浅复制只复制一层对象的属性,而深复制则递归复制了所有层级

1.因为浅复制只会将对象的各个属性进行依次复制,并不会进行递归复制,而 JavaScript 存储对象都是存地址的,所以浅复制会导致 obj.arr 和 shallowObj.arr 指向同一块内存地址

shallowObj.arr[1] = 5;
obj.arr[1] // = 5

2.而深复制则不同,它不仅将原对象的各个属性逐个复制出去,而且将原对象各个属性所包含的对象也依次采用深复制的方法递归复制到新对象上。这就不会存在上面 obj 和 shallowObj 的 arr 属性指向同一个对象的问题。

var obj = { a:1, arr: [1,2] };
var obj2 = deepCopy(obj);

11. 从输入URL到页面展示,中间发生了什么?

1.在浏览器输入URL  www.github.com

2.浏览器解析URL,

3.浏览器与ISP通信,通过DNS查找到域名对应的IP,发给浏览器

4.浏览器将拿这个IP地址和URL中的端口号(HTTP协议默认端口号是80,HTTPS默认端口号是443),打开一个TCP套接字连接。这时,浏览器和服务器就建立了连接。

5.浏览器发送一个HTTP请求至Web服务器,去获取www.github.com的主页

6.Web服务器接收请求,并查找HTML页面。如果该页面存在,该Web服务器准备响应并把它发回给你的浏览器。如果服务器找不到你请求的页面,它将发送一个404错误消息,404表示“页面未找到”

7.浏览器接收到的HTML页面从头到尾扫描一遍,并去寻找其它相关的资源,如图片、CSS文件、JavaScript脚本文件等等,通过相同方式获取到资源

8.一旦浏览器加载完HTML涉及到的所有资源,页面最终会加载在浏览器窗体里,并关闭与服务器的连接。

12. 强缓存和协商缓存

强缓存(Expires/max-age)
强致缓存。在HTTP1.0中强缓存通过Expires响应头实现。
在HTTP1.1中,Cache-control响应头实现,其中max-age=xxx表示缓存资源将在xxx秒后过期。

协商缓存(Last-Modified/E-tag)
协商缓存。在HTTP1.0中第一次请求资源时通过服务器设置Last-Modified响应头,填入最后修改时间。在之后的每次请求中都会在请求头中带上If-Modified-Since字段,如果未更新就返回304,指导浏览器从本地缓存中读取。
在HTTP1.1中,Etag设置响应头缓存标志。请求头附带If-None-Match。

强缓存和协商缓存的区别总结:
1.强缓存只有首次请求会跟服务端通信,读取缓存资源时不用发送请求。返回200。
2.协商缓存总会与服务器交互,第一次是拿数据和E-tag的过程,之后每次凭E-tag询问是否更新。命中缓存返回304。
3.二者之间最大的区别就是:强缓存只通信一次;协商缓存每次都通信询问。

13. Vue的diff算法和DOM原理

在数据发生变化,vue是先根据真实DOM生成一颗 virtual DOM ,当 virtual DOM 某个节点的数据改变后会生成一个新的 Vnode ,然后 Vnode 和 oldVnode 作对比,发现有不一样的地方就直接修改在真实的DOM上,然后使 oldVnode 的值为 Vnode ,来实现更新节点。

1.原理简述:
(1)先去同级比较,然后再去比较子节点

(2)先去判断一方有子节点一方没有子节点的情况

(3)比较都有子节点的情况

(4)递归比较子节点

虚拟 DOM 的实现原理主要包括以下 3 部分:
(1)用 JavaScript 对象模拟真实 DOM 树,对真实 DOM 进行抽象;
(2)diff 算法 — 比较两棵虚拟 DOM 树的差异;
(3)pach 算法 — 将两个虚拟 DOM 对象的差异应用到真正的 DOM 树。

14. promise是什么?怎么使用?

1、主要用于异步计算
2、可以将异步操作队列化,按照期望的顺序执行,返回符合预期的结果
3、可以在对象之间传递和操作promise,帮助我们处理队列

首先,Promise 是一个构造函数,对回调函数的一种封装,对异步编程的一种改进,用同步的方式表达出来。可以说Promise是ajax的执行状态管理工具,它还应用到Vue里的fetch等方面。该构造函数身上有两个方法:Promise.all(),和Promise.race()。
其实,我们应用的重点是:new出来的promise对象。它有三种状态:pending(进行中),resolved(已完成),rejected(已失败),状态一旦发生,就不能改变。执行new的时候状态就开始变化。promise对象身上有两个方法:then(),和catch()。

语法: var oP =new Promise(function(resolve,reject){

reject(data); || resolve(data);

}) ;

oP.then(function(data){ }, function(data){ }) //第一参数是在oP状态为resolved时执行。第二参数是在oP状态为rejected时执行(也叫错误捕获)。

oP.catch( function(data){ })。 //捕获错误,出错时不捕获错误会报错。

oP.then(function(data){ }).then(function(data){ }) //then()还可以传递,但是数据data不会传递(即第二个data为undefined)。

oP.then(function(data){ }, function(data){ }).catch( function(data){ }) //catch不会传递执行错误,只会执行一次(即这里的catch不会执行)。

所以,我们在遇到回调函数层层嵌套时,就可以将函数返回一个promise对象。利用 then方法+catch方法 来处理。

二、使用promise的好处是:
1.代码结构更加扁平且更可读,清晰明了。

2.能解决回调地狱问题。

3.可将数据请求和业务逻辑分离开来。

4.便于管理维护。

5.能更好的捕获错误。

15. Vue与Angular以及React的区别?

1.与AngularJS的区别
相同点:
都支持指令:内置指令和自定义指令;都支持过滤器:内置过滤器和自定义过滤器;都支持双向数据绑定;都不支持低端浏览器。

不同点:
AngularJS的学习成本高,比如增加了Dependency Injection特性,而Vue.js本身提供的API都比较简单、直观;在性能上,AngularJS依赖对数据做脏检查,所以Watcher越多越慢;Vue.js使用基于依赖追踪的观察并且使用异步队列更新,所有的数据都是独立触发的。

2.与React的区别
相同点:
React采用特殊的JSX语法,Vue.js在组件开发中也推崇编写.vue特殊文件格式,对文件内容都有一些约定,两者都需要编译后使用;中心思想相同:一切都是组件,组件实例之间可以嵌套;都提供合理的钩子函数,可以让开发者定制化地去处理需求;都不内置列数AJAX,Route等功能到核心包,而是以插件的方式加载;在组件开发中都支持mixins的特性。
不同点:
React采用的Virtual DOM会对渲染出来的结果做脏检查;Vue.js在模板中提供了指令,过滤器等,可以非常方便,快捷地操作Virtual DOM。

16. vue等单页面应用及其优缺点

优点:Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件,核心是一个响应的数据绑定系统。MVVM、数据驱动、组件化、轻量、简洁、高效、快速、模块友好。
缺点:不支持低版本的浏览器,最低只支持到IE9;不利于SEO的优化(如果要支持SEO,建议通过服务端来进行渲染组件);第一次加载首页耗时相对长一些;不可以使用浏览器的导航按钮需要自行实现前进、后退。

17. promise、async、await的理解

1、Promise中的函数的第一个参数是回调函数,resolve用来触发then里面的代码,第二个参数是回调函数,reject用来触发catch中的代码,throw new Error();也可以触发catch,

2、await可以是Promise同步,即不会立即执行Proimse外面(或者说下面)的代码,而await只能用在async标记的函数中,这样async函数本身就是异步的,而async函数里面的代码是同步的

3、async本身是异步的,可以这样理解,async函数执行到await的时候就立即返回,开始执行async下面的代码,与await等待执行的代码同时执行

18. Vue项目优化

1.代码层面的优化
v-if 和 v-show 区分使用场景
computed 和 watch 区分使用场景
v-for 遍历必须为 item 添加 key,且避免同时使用 v-if
长列表性能优化
事件的销毁
图片资源懒加载
路由懒加载
第三方插件的按需引入
优化无限列表性能
服务端渲染 SSR or 预渲染

2.Webpack 层面的优化
Webpack 对图片进行压缩
减少 ES6 转为 ES5 的冗余代码
提取公共代码
模板预编译
提取组件的 CSS
优化 SourceMap
构建结果输出分析
Vue 项目的编译优化

3.基础的 Web 技术的优化
开启 gzip 压缩
浏览器缓存
CDN 的使用
使用 Chrome Performance 查找性能瓶颈

19. 前端性能优化

前端优化的途径有很多,大致可以分为两类,第一类是页面级别的优化,例如 HTTP请求数、脚本的无阻塞加载、内联脚本的位置优化等 ;第二类则是代码级别的优化,例如 Javascript中的DOM 操作优化、CSS选择符优化、图片优化以及 HTML结构优化等等。

一、页面级优化:
1、减少 HTTP 请求:浏览器一般同时响应请求为4个(PC 一般为4个,Android 支持4个,IOS 5后可支持6个)
减少 HTTP请求数的主要途径包括:
合理设置 HTTP缓存、资源合并与压缩
2、使用外联式引入CSS、JavaScript
3、使用首屏加载:首屏的快速显示,可以大大提升用户对页面速度的感知,因此应尽量针对首屏的快速显示做优化按需加载:将不影响首屏的资源和当前屏幕资源不用的资源放到用户需要时才加载,可以大大提升重要资源的显示速度和降低总体流量。但是这也会导致大量重绘,影响渲染性能
4、lazyload、滚动加载、media query、预加载
5、使用其他方式代替图片(CSS3,SVG,IconFont)、使用 Srcset (主要移动端)、选择合适的图片(webP优于JPG,PNG8优于GIF)、选择合适的大小(首次加载不大于1014KB,不宽于640(基于手机的一般宽度))
6、CSS 写在头部(阻塞 DOM 渲染,不阻塞加载,内联会阻塞加载)
如果将 CSS放在其他地方比如 BODY中,则浏览器有可能还未下载和解析CSS,就已经开始渲染页面了,这就导致页面由无 CSS状态跳转到 CSS状态,用户体验比较糟糕。除此之外,有些浏览器会在 CSS下载完成后才开始渲染页面,如果 CSS放在靠下的位置则会导致浏览器将渲染时间推迟。),JavaScript 写在尾部或异步(js文件默认阻塞加载和渲染)

二、代码优化
css代码优化
1、尽量避免在 HTML标签中写 Style 属性
2、避免 CSS 表达式:CSS 表达式的执行需跳出 CSS 的渲染
3、移除空的 CSS 规则:空的 CSS 规则增加了 CSS 文件的大小,且影响 CSS 树的执行
4、使用flexbox来布局
5、正确使用display的属性:
display:inline 后边不应再使用 width、height、margin、padding 以及 float
display:inline-block 后不应该使用 float
display:block 后不应该再使用 vertical-align
display:table 后不应该再使用 margin 或 float
不滥用 float :float 在渲染时的计算量比较大,尽量减少使用
不滥用 Web 字体:Web字体需要下载,解析,重绘当前页面,尽量减少使用
不声明过多的 font-size: 尽量使用语义化标签的默认字体大小,提高 CSS 树的效率值为 0 时不需要任何单位
6、标准化各种浏览器的前缀
没前缀应放在最后
CSS 动画只用(-webkit- 无前缀 两种即可)
其他前缀为 -webkit- 、-moz- 、-ms- 、无前缀 四种
7、css选择符:浏览器对选择符的解析是从右往左进行的

JavaScript执行优化
1、减少dom的重绘和回流
2、避免不必要的 DOM 操作
3、尽量改变 Class 而不是 Style ,使用 classList 代替 className
4、避免使用 document.write()会重绘整个页面
5、缓存 DOM 选择与计算:每次 DOM 选择都要计算,用一个变量保存这个值
6、尽量使用事件代理,避免批量绑定事件
7、尽量使用 ID 选择器:ID选择器是最快的
8、Touch 事件优化:使用 touchstart 、touchend 代替 click,但注意 Touch 响应过快,易引发误操作

渲染优化
1、减少 DOM 节点:DOM 节点太多影响页面的渲染,应尽量减少 DOM 节点
2、动画优化:
尽量使用 CSS3 动画
适当使用 Canvas 动画, 5 个元素以内使用 CSS 动画(IOS8可使用webGL)
增加响应变化的时间间隔,减少重绘次数
GPU 加速:CSS中以下属性(CSS3 transitions、CSS3 3D transforms、Opacity、Canvas、webGL、Video)来触发 GPU 渲染,但过度使用会引发手机耗电增加。

20. Vue3.0的特性

1.监测机制的改变
Vue3.0 将带来基于代理 Proxy 的 observer 实现,提供全语言覆盖的反应性跟踪。这消除了 Vue 2 当中基于 Object.defineProperty 的实现所存在的很多限制:①只能监测属性,不能监测对象;②检测属性的添加和删除;③检测数组索引和长度的变更;④支持 Map、Set、WeakMap 和 WeakSet。
新的 observer 还提供了以下特性:
用于创建 observable 的公开 API。这为中小规模场景提供了简单轻量级的跨组件状态管理解决方案。
默认采用惰性观察。在 2.x 中,不管反应式数据有多大,都会在启动时被观察到。如果你的数据集很大,这可能会在应用启动时带来明显的开销。在 3.x 中,只观察用于渲染应用程序最初可见部分的数据。
更精确的变更通知。在 2.x 中,通过 Vue.set 强制添加新属性将导致依赖于该对象的 watcher 收到变更通知。在 3.x 中,只有依赖于特定属性的 watcher 才会收到通知。
不可变的 observable:我们可以创建值的“不可变”版本(即使是嵌套属性),除非系统在内部暂时将其“解禁”。这个机制可用于冻结 prop 传递或 Vuex 状态树以外的变化。
更好的调试功能:我们可以使用新的 renderTracked 和 renderTriggered 钩子精确地跟踪组件在什么时候以及为什么重新渲染。

2.模板
模板方面没有大的变更,只改了作用域插槽,2.x 的机制导致作用域插槽变了,父组件会重新渲染,而 3.0 把作用域插槽改成了函数的方式,这样只会影响子组件的重新渲染,提升了渲染的性能。
同时,对于 render 函数的方面,vue3.0 也会进行一系列更改来方便习惯直接使用 api 来生成 vdom 。
3.对象式的组件声明方式
vue2.x 中的组件是通过声明的方式传入一系列 option,和 TypeScript 的结合需要通过一些装饰器的方式来做,虽然能实现功能,但是比较麻烦。3.0 修改了组件的声明方式,改成了类式的写法,这样使得和 TypeScript 的结合变得很容易。
此外,vue 的源码也改用了 TypeScript 来写。其实当代码的功能复杂之后,必须有一个静态类型系统来做一些辅助管理。现在 vue3.0 也全面改用 TypeScript 来重写了,更是使得对外暴露的 api 更容易结合 TypeScript。静态类型系统对于复杂代码的维护确实很有必要。
4.其它方面的更改
vue3.0 的改变是全面的,上面只涉及到主要的 3 个方面,还有一些其它的更改:
支持自定义渲染器,从而使得 weex 可以通过自定义渲染器的方式来扩展,而不是直接 fork 源码来改的方式。
支持 Fragment(多个根节点)和 Protal(在 dom 其它部分渲染组建内容)组件,针对一些特殊的场景做了处理。
基于 treeshaking 优化,提供了更多的内置功能。

21. 防抖和节流区别

函数防抖:将多次操作合并为一次操作进行。原理是维护一个计时器,规定在delay时间后触发函数,但是在delay时间内再次触发的话,就会取消之前的计时器而重新设置。这样一来,只有最后一次操作能被触发。

函数节流:使得一定时间内只触发一次函数。原理是通过判断是否有延迟调用函数未执行。

区别: 函数节流不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数,而函数防抖只是在最后一次事件后才触发一次函数。 比如在页面的无限加载场景下,我们需要用户在滚动页面时,每隔一段时间发一次 Ajax 请求,而不是在用户停下滚动页面操作时才去请求数据。这样的场景,就适合用节流技术来实现。

22. 跨域

1.跨域:

当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域

同协议,同端口,同域名才属于同一域。

ajax出于安全考虑禁止跨域,但是src可以跨域。

2.跨距解决方法:

【1】设置document.domain解决无法读取非同源网页的 Cookie问题

此方案仅限主域相同,子域不同的跨域应用场景。

【2】跨文档通信 API:window.postMessage(data,url)

它可用于解决以下方面的问题:

  • 页面和其打开的新窗口的数据传递
  • 多窗口之间消息传递
  • 页面与嵌套的iframe消息传递
  • 上面三个场景的跨域数据传递

【3】JSONP

【4】CORS

CORS 是跨域资源分享(Cross-Origin Resource Sharing)的缩写。它是 W3C 标准,属于跨源 AJAX 请求的根本解决方法。

1、普通跨域请求:只需服务器端设置Access-Control-Allow-Origin

2、带cookie跨域请求:前后端都需要进行设置

23. JS的循环机制

1、主线程读取JS代码,此时为同步环境,形成相应的堆和执行栈;

2、主线程遇到异步任务,指给对应的异步进程进行处理(WEB API);

3、异步进程处理完毕(Ajax返回、DOM事件处罚、Timer到等),将相应的异步任务推入任务队列;

4、主线程执行完毕,查询任务队列,如果存在任务,则取出一个任务推入主线程处理(先进先出);

5、重复执行step2、3、4;称为事件循环。

macro-task(宏任务):包括整体代码script,setTimeout,setInterval

micro-task(微任务):Promise,process.nextTick

24. 原型和原型链

1、每个函数都有prototype(原型)属性,这个属性是一个指针,指向一个对象,这个对象的用途是包含特定类型的所有实例共享的属性和方法,即这个原型对象是用来给实例共享属性和方法的。
而每个实例内部都有一个指向原型对象的指针。

2、每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含指向原型对象内部的指针。我们让原型对象的实例(1)等于另一个原型对象(2),
此时原型对象(2)将包含一个指向原型对象(1)的指针,
再让原型对象(2)的实例等于原型对象(3),如此层层递进就构成了实例和原型的链条,这就是原型链的概念

25. WebPack打包

 初始化参数->开始编译->确定入口->编译模块->完成模块编译->输出资源->输出完成

我们可以对于webpack配置做以下扩展和优化:

1、CommonJS模块化规范的解决方案: 设置output.libraryTarget='commonjs2'使输出的代码符合CommonJS2 模块化规范,以供给其它模块导入使用

2、输出ES5代码的解决方案:使用babel-loader把 ES6 代码转换成 ES5 的代码。再通过开启devtool: 'source-map'输出SourceMap以发布调试。

3、Npm包大小尽量小的解决方案:Babel 在把 ES6 代码转换成 ES5 代码时会注入一些辅助函数,最终导致每个输出的文件中都包含这段辅助函数的代码,造成了代码的冗余。解决方法是修改.babelrc文件,为其加入transform-runtime插件

4、不能将依赖模块打包到NPM模块中的解决方案:使用externals配置项来告诉webpack哪些模块不需要打包。

5、对于依赖的资源文件打包的解决方案:通过css-loader和extract-text-webpack-plugin来实现

用webpack优化前端性能是指优化webpack的输出结果,让打包的最终结果在浏览器运行快速高效。

1、压缩代码。删除多余的代码、注释、简化代码的写法等等方式。可以利用webpack的UglifyJsPlugin和ParallelUglifyPlugin来压缩JS文件, 利用cssnano(css-loader?minimize)来压缩css

2、利用CDN加速。在构建过程中,将引用的静态资源路径修改为CDN上对应的路径。可以利用webpack对于output参数和各loader的publicPath参数来修改资源路径

3、删除死代码(Tree Shaking)。将代码中永远不会走到的片段删除掉。可以通过在启动webpack时追加参数--optimize-minimize来实现

4、提取公共代码。

26. 

 

原文地址:https://www.cnblogs.com/shusonghe/p/12955736.html