Q1:Vue双向绑定的原理是什么?
知识点:Vue2.0, Vue3.0, 实现过程
解答:A1
Q2:input输入框的提交、清空、验证
知识点:Vue-model
解答:A2
Q3:列表 - 行 背景实现高亮,单行位置上移
知识点:事件代理(唯一角标)
解答:A3
Q4:Vuex 修改状态过程
知识点:State Mutation Action
解答:A4
Q5:Promise 实现3秒后打印 1
知识点:Promise
解答:A5
Q6:css scss less stylus区别
知识点:CSS预处理器
解答:A6
Q7:封装组件
知识点:场景、组件库、流程
解答:A7
Q8:懒加载、预加载的应用场景
知识点:图片/视频、组件、路由
解答:A8
Q9:nuxtjs 是什么,什么场景用
知识点:服务端渲染,优缺点
解答:A10
Q10:个人技能、项目技术栈
知识点:Vue-model
知识点:Vue双向绑定的原理是什么?
Q11:负责什么内容,最近项目中遇到的难题是什么
知识点:Vue-model
知识点:Vue双向绑定的原理是什么?
Q12:皮肤切换怎么实现
知识点:theme、link、类选择器
解答:A12
Q13:地图上的图标过多时候怎么处理
知识点:聚合点, 批量加入
解答:A13
Q14:项目数据量是多大
知识点:Vue-model
知识点:Vue双向绑定的原理是什么?
Q15:什么是宏任务 / 微任务? 哪些属于宏任务 / 微任务?
知识点:Promise
解答:A15
Q16:虚拟DOM怎么实现,用来做什么,vue和react的区别是什么
知识点:Vue双向绑定的原理是什么?
解答:Vue双向绑定的原理是什么?
Q17:typescript
知识点:Vue双向绑定的原理是什么?
解答:Vue双向绑定的原理是什么?
Q18:vue-cli, 脚手架, webpack
知识点:Vue双向绑定的原理是什么?
解答:Vue双向绑定的原理是什么?
Q19:Vue-router 路由封装, 路由优化
知识点:Vue双向绑定的原理是什么?
解答:Vue双向绑定的原理是什么?
Q20:封装的指令
知识点:Vue双向绑定的原理是什么?
解答:Vue双向绑定的原理是什么?
Q21:请求头攻击, 植入tostring方法, 其他攻击方式和解决方法
知识点:Vue双向绑定的原理是什么?
解答:Vue双向绑定的原理是什么?
Q22:用css隐藏内容的方法, display:none/hidden, 脱离文档流
知识点:Vue双向绑定的原理是什么?
Q23:重绘和回流
知识点:Vue双向绑定的原理是什么?
解答:Vue双向绑定的原理是什么?
Q24:原型链, obj寻找方法的路线
知识点:Vue双向绑定的原理是什么?
解答:Vue双向绑定的原理是什么?
Q25:let const var, 为什么const的obj 可以被重新赋值
知识点:Vue双向绑定的原理是什么?
解答:Vue双向绑定的原理是什么?
Q26:this指向类型, call apply bind
知识点:Vue双向绑定的原理是什么?
解答:Vue双向绑定的原理是什么?
Q27:深浅拷贝
知识点:Vue双向绑定的原理是什么?
解答:Vue双向绑定的原理是什么?
Q28:Vue双向绑定的原理是什么?
知识点:Vue双向绑定的原理是什么?
解答:Vue双向绑定的原理是什么?
Q29:数据处理, 清除重复数据, set key值的唯一性, 不使用lodash
知识点:Vue双向绑定的原理是什么?
解答:Vue双向绑定的原理是什么?
Q30:冒泡事件, 捕获事件
知识点:Vue双向绑定的原理是什么?
解答:Vue双向绑定的原理是什么?
Q31:跨域问题, 解决方法
知识点:Vue双向绑定的原理是什么?
解答:Vue双向绑定的原理是什么?
Q32:MVVM架构
知识点:Vue双向绑定的原理是什么?
解答:Vue双向绑定的原理是什么?
Q33:react基础
知识点:Vue双向绑定的原理是什么?
解答:Vue双向绑定的原理是什么?
Q34:性能优化, performance, 白屏
知识点:Vue双向绑定的原理是什么?
解答:Vue双向绑定的原理是什么?
Q35:UI组件库, antd, 二次封装
知识点:Vue双向绑定的原理是什么?
解答:Vue双向绑定的原理是什么?
Q36:Vue3
知识点:Vue双向绑定的原理是什么?
解答:Vue双向绑定的原理是什么?
Q37:uniapp基础
知识点:Vue双向绑定的原理是什么?
解答:Vue双向绑定的原理是什么?
Q38:http
知识点:Vue双向绑定的原理是什么?
解答:Vue双向绑定的原理是什么?
Q39:axios封装
知识点:Vue双向绑定的原理是什么?
解答:Vue双向绑定的原理是什么?
Q40:app适配方案
知识点:Vue双向绑定的原理是什么?
解答:Vue双向绑定的原理是什么?
Q41:图片压缩
知识点:Vue双向绑定的原理是什么?
解答:Vue双向绑定的原理是什么?
Q42:排序:冒泡排序, 快速排序
知识点:Vue双向绑定的原理是什么?
解答:Vue双向绑定的原理是什么?
Q43:get, post, 不一样的方式
知识点:Vue双向绑定的原理是什么?
解答:Vue双向绑定的原理是什么?
Q44:闭包
知识点:Vue双向绑定的原理是什么?
解答:Vue双向绑定的原理是什么?
Q45:柯里化
知识点:Vue双向绑定的原理是什么?
解答:Vue双向绑定的原理是什么?
Q46:对象继承
知识点:Vue双向绑定的原理是什么?
解答:Vue双向绑定的原理是什么?
Q47:工厂模式
知识点:Vue双向绑定的原理是什么?
解答:Vue双向绑定的原理是什么?
Q48:Vue双向绑定的原理是什么?
知识点:Vue双向绑定的原理是什么?
解答:Vue双向绑定的原理是什么?
Q49:取整, 随机数
知识点:Vue双向绑定的原理是什么?
解答:Vue双向绑定的原理是什么?
Q50:定时器
知识点:Vue双向绑定的原理是什么?
解答:Vue双向绑定的原理是什么?
Q51:数组方法, 传参方式
知识点:Vue双向绑定的原理是什么?
解答:Vue双向绑定的原理是什么?
Q52:缓存, scoket, webscoket
知识点:Vue双向绑定的原理是什么?
解答:Vue双向绑定的原理是什么?
Q53:内存移除, 内存泄漏
知识点:Vue双向绑定的原理是什么?
解答:Vue双向绑定的原理是什么?
Q54:时间格式化
知识点:Vue双向绑定的原理是什么?
解答:Vue双向绑定的原理是什么?
Q55:常用状态码
知识点:Vue双向绑定的原理是什么?
解答:Vue双向绑定的原理是什么?
Q56:浏览器输入url做了什么
知识点:Vue双向绑定的原理是什么?
解答:Vue双向绑定的原理是什么?
Q57:echarts 切换后不显示图表, resize, nextTick
知识点:Vue双向绑定的原理是什么?
解答:Vue双向绑定的原理是什么?
Q57:css 3 新属性 css动画 flex 数据类型 正则 函数 分配方式 this ES6 ES5 数据去重 ES6新增 数组合并 深拷贝 方法 null undefined 什么是原型 generater 事件循环的机制 数组key vue双向绑定 watch深度监听 对象监管 lefttic 事件循环 父子传值 不常规 请求200.. fetch请求 xpath 数据传递方式
js事件循环 axios封装 rabitmq 难点 微信小程序为什么初次加载快 URL输入之后经历了什么 生命周期 双向绑定在哪个阶段 算法题 webpack 性能优化 跨域 攻击 怎么学前端
打包 适配安卓 二次组件封装 适配 下拉刷新 加载更多 性能优化 节流防抖 富文本 编辑 排版
canvas 第三方库 项目比重 node.js 登录流程 token 账号 用户名 请求信息 路由跳转 ?id 列表 到详情 获取id 详情页 url ?adc='...' 获取到... ES6新增的特性 simble this指向 箭头函数和普通 跨域 跨域 本地环境请求 跨域问题 怎么配置 有一个project参数 访问某个用户转换后后端交易的端口 flex布局
node.js 技术点 难点 工作流程 前后端 新技术 swg 定义数据类型 json结构 氛围 nexttick
webpack
配置 ESlink 配置渲染出口HTML 插件 loader plague 区别
动态加载 刚开始一起加载 懒加载
trunk 写名字 不在一个包里面
打包引入
功能优化 引入了防抖节流
项目构建 通过 axios 公共模块抽出来 拦截器做优化
json 错误抽出来
指令
举例 原理 什么行为 什么生命周期
封装组件
ES6特性
权限 匹配权限 建立权限
指令 button 哪些权限的key 传给自定义指令 找到我对应的key 找到就渲染 找不到就不渲染 登录之后返回list 找不到不渲染 自定义指令的声明周期
vue 对象新增属性 页面没刷新
因为在定义对象 新增的key不是响应式的 vue $set 新增对象的响应式添加 不是.
类似 数组新增元素 是不是响应式
set 无重复去重
array this指向
H5动画
知识点:Vue双向绑定的原理是什么?
解答:Vue双向绑定的原理是什么?
A1:Vue双向绑定的原理是什么?
解答:
- Vue2.0 采用的是 Object.defineProperty 进行 数据劫持
- Vue3.0 采用Proxy来实现数据劫持
- 实现流程
- new 一个 MVVM() 作为入口函数
- 实现一个 Compile(模板编译), 对指令进行解析, 初始化视图, 并且订阅数据的变更, 绑定好更新函数
- 实现一个Observer(数据劫持), 对属性的
getter和setter方法进行劫持, 在对象的属性发生变化时更新视图 - 实现一个Watcher(观察者), 作为 Compile 和 Observer 的中介点, 在接收数据变更的同时, 让Dep(订阅器)添加当前的Watcher, 并及时通知视图进行 Updata(数据更新)
补充:
- 切入点:从应用层以 input 为例, 通过 v-model 实现与 data 的双向绑定来切入
- Compile(模板编译):将真实DOM移入到内存中 => 编译(提取到需要的元素节点和文本节点) => 编译好的fragment放到页面中(至此,data中定义的数据已经完全渲染在页面上了)
- Observer(数据劫持):对
data中的每一个属性值进行监测, 只要数据变化了, 就要更新视图 - Watcher(观察者):对新值和老值进行比较, 如果发生变化, 就调用更新方法, 进行视图更新
数据劫持主要使用了 Object.defineProperty() :
- 在对 data 数据中的原有属性改为 get 和 set 之前, 需要对 data 进行判断, 排除不是对象和数据不存在的情况
- 因为 data 中的数据可能是多层嵌套的对象, 所以要进行深层递归, 但是这里的递归只会为 data 中初始的数据
get进行劫持, 对新添加的不会 - 基于上面的缺陷, 所以需要为数据添加
set方法时, 也对数据进行劫持
发布 - 订阅模式 : 发布-订阅模式又叫观察者模式,它定义对象间的一种一对多的依赖关系,当一个对象的状态改变时,所有依赖于它的对象都将得到通知。
Proxy 对比 defineProperty :
- Proxy 可以直接监听对象而非属性
- Proxy 可以直接监听数组的变化(defineProperty只有八种方法)
- Proxy 有更多的拦截方法, 返回的是一个新对象, 劣势是兼容性问题
A2:input输入框的提交、清空、验证
解答:
清空:输入框绑定 Vue-model @click => data 变量:"" => 当点击事件触发,设置变量为空
验证 / 提交 :绑定点击事件, 事件触发调用 回调函数, 通过 vue-model 中的 value 验证 / 提交
A3:列表 - 行 背景实现高亮,单行位置上移
解答:
列表 - 行 高亮: 给 ul 添加事件 @click="select_li(index), 当点击 li 时触发 li 的class样式 :class="[selectLi ==index?'active':'']"
单行数据上下移动:
WaListData.splice(i-1, 1)删除下个索引的数据WaListData.splice(i-1, 1, WaListData[i])用当前索引数据(WaListData[i])替换下个索引的数据WaListData[i]= WaListData.splice(i-1, 1, WaListData[i])[0]当WaListData.splice()方法执行后会返回删除的数据,并将删除的数据赋值给当前索引
A4:Vuex 修改状态过程
解答:
为什么要使用Vuex:
- 多个视图依赖同一个状态
- 来自不同视图的行为需要变更同一个状态
什么是Vuex: Vuex 是一个专为 Vue.js 应用程序开发的状态管理插件。它采用集中式存储管理应用的所有组件的状态, 除了储存状态, 还可以记录日志、追踪变更。
State:
- Vuex的核心就是仓库store,这个store实例会被注入到所有子组件里面,里面的state属性保存着我们的状态。
- 其他组件可以通过
计算属性 computed: { this.$store.state }来获得; - 根实例中注册 store 选项, 该 store 实例会注入到根组件下的所有子组件中, 且子组件能通过 this.$store 访问到
mapState:
- mapState方法可以 获取多个状态
- 使用 mapState 后需要把 msg() 放入 mapState 中,不然会报错( 如果使用展开运算符..., computed 属性不需要改造)
Getter: Getter 就是对状态进行处理,当状态要进行某些操作时,可以通过getter处理过后再返回给组件使用,之后再在其他组件的computed里面去调用getter来获取想要的状态
mapGetters:
- mapGetters 辅助函数仅仅是将 store 中的 getter 映射到局部计算属性,可以在组件里面引入多个getter
- 如果 computed 属性包含其他计算方法,那就只能使用展开运算符的写法,这里跟 mapState 有点区别,其他计算属性如果写在mapGetter里面会报错,说不存在的getter,或者指定别名,然后再模板里面调用
Mutation:
- 修改store里面的状态时,我们不是在组件里面直接去修改它们,而是通过mutation里面的方法来进行修改,这样有利于追踪状态的改变
- 在其他组件里面,通过定义methods并绑定事件来触发改变
- Mutation 必须是同步函数
mapMutation: 跟前面那几个函数一个道理, 都是为了简化调用
Action:
- Action 提交的是 Mutation , 而不是直接变更状态
- Action 可以包含任意异步操作
mapAction: 同前面map...辅助函数类型, 用来映射 Action 里面的方法
Module: 当所有状态集中在一个对象中时,会变的相当臃肿,这个时候就需要模块的管理办法。
详解:Vuex学习手记
A5:Promise 实现3秒后打印 1
解答:
// Promise.resolve().then(()=>{
function five() {
return new Promise(resolve=>{
setTimeout(()=>{
console.log("1")
},3000)
})
}
five()
拓展题目: 用promise实现,红色三秒打印一次、绿色两秒打印一次、黄色一秒打印一次,三种颜色循环不断交替打印。
function red() {
console.log("red");
}
function green() {
console.log("green");
}
function yellow() {
console.log("yellow");
}
function light(time,name){
return new Promise(resolve=>{
setTimeout(()=>{
name()
resolve()
},time)
})
}
function step(){
Promise.resolve().then(()=>{
return light(3000,red)
}).then(()=>{
return light(2000,green)
}).then(()=>{
return light(1000,yellow)
}).then(()=>{
// 黄色循环完毕再调用一次step,实现不断循环打印
return step()
})
}
step()
Promise的含义:
- Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。
- 有了
Promise对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。 - 从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。
- Promise 一共有三种状态:Pending(进行中)、Fulfilled(已成功) 和 Rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。
Promise也有一些缺点。首先,无法取消Promise,一旦新建它就会立即执行,无法中途取消。其次,如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。第三,当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。
实现逻辑:
- Promise 是一个类,在执行这个类的时候会传入一个执行器,这个执行器会立即执行
- Promise 会有三种状态:Pending 等待、Fulfilled 完成、Rejected 失败
- 状态只能由 Pending --> Fulfilled 或者 Pending --> Rejected,且一但发生改变便不可二次修改;
- Promise 中使用 resolve 和 reject 两个函数来更改状态;
- then 方法内部做但事情就是状态判断
- 如果状态是成功,调用成功回调函数
- 如果状态是失败,调用失败回调函数
基本用法:
Promise对象是一个构造函数,用来生成Promise实例
const promise = new Promise(function(resolve, reject) {
// ... some code
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数。
promise.then(function(value) {
// success
}, function(error) {
// failure
});
Promise.prototype.then
then方法作用是为 Promise 实例添加状态改变时的回调函数。then方法返回的是一个新的Promise实例。因此可以采用链式写法,即then方法后面再调用另一个then方法。
Promise.prototype.catch: Promise.prototype.catch()方法是.then(null, rejection)或.then(undefined, rejection)的别名,用于指定发生错误时的回调函数。
getJSON('/posts.json').then(function(posts) {
// ...
}).catch(function(error) {
// 处理 getJSON 和 前一个回调函数运行时发生的错误
console.log('发生错误!', error);
});
Promise.prototype.finally: finally()方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。
promise
.then(result => {···})
.catch(error => {···})
.finally(() => {···});
Promise.all:
Promise.all()方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。
const p = Promise.all([p1, p2, p3]);
Promise.race: Promise.race()方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。
const p = Promise.all([p1, p2, p3]);
Promise.allSettled: Promise.allSettled()方法接受一组 Promise 实例作为参数,包装成一个新的 Promise 实例。只有等到所有这些参数实例都返回结果,不管是fulfilled还是rejected,包装实例才会结束。
const promises = [
fetch('/api-1'),
fetch('/api-2'),
fetch('/api-3'),
];
await Promise.allSettled(promises);
removeLoadingIndicator();
Promise.any: 该方法接受一组 Promise 实例作为参数,包装成一个新的 Promise 实例返回。
Promise.any([
fetch('https://v8.dev/').then(() => 'home'),
fetch('https://v8.dev/blog').then(() => 'blog'),
fetch('https://v8.dev/docs').then(() => 'docs')
]).then((first) => { // 只要有一个 fetch() 请求成功
console.log(first);
}).catch((error) => { // 所有三个 fetch() 全部请求失败
console.log(error);
});
Promise.resolve: 有时需要将现有对象转为 Promise 对象,Promise.resolve()方法就起到这个作用。
const jsPromise = Promise.resolve($.ajax('/whatever.json'));
Promise.reject: Promise.reject(reason)方法也会返回一个新的 Promise 实例,该实例的状态为rejected。
const jsPromise = Promise.resolve($.ajax('/whatever.json'));
加载图片: 可以将图片的加载写成一个Promise,一旦加载完成,Promise的状态就发生变化。
const preloadImage = function (path) {
return new Promise(function (resolve, reject) {
const image = new Image();
image.onload = resolve;
image.onerror = reject;
image.src = path;
});
};
详解:A5
A6:css scss less stylus区别
解答:
CSS预处理器解决了css的一些缺陷:
- 语法不够强大,不能够嵌套书写,不利于模块化开发
- 没有变量和逻辑上的复用机制
变量: 就像其他编程语言一样,免于多处修改。
- Sass:使用
$对变量进行声明, 变量名和变量值使用冒号进行分割 - Less:使用
@对变量进行声明 - Stylus:声明变量没有任何限定,结尾的分号可有可无,但变量名和变量值之间必须要有
=。
作用域: 有了变量,就必须得有作用域进行管理。就像js一样,它会从局部作用域开始往上查找变量。
- Sass:它的方式是三者中最差的,不存在全局变量的概念
- Less:它的方式和js比较相似,逐级往上查找变量
- Stylus:它的方式和Less比较相似,但是它和Sass一样更倾向于指令式查找
嵌套: 对于css来说,有嵌套的写法无疑是完美的,更像是父子层级之间明确关系,三者在这处的处理都是一样的
A7:封装组件
解答:
- 组件库:大部分组件都是基于antd的二次封装
- 场景:有视频组件, 以及表单组件, 比如input和 步骤条, 步骤条可以扩展
流程:
v-model绑定 value( 非默认必须包含在props中 )- 绑定事件绑定事件(如果时自定义需要通过
emit自定义事件) props封装组件把 prop 的类型和默认值都定义了并且说明清楚,验证规则validatorslot插槽,自定义显示内容的方法$refs获取内部暴漏的事件
详情:
组件:通用、灵活、高内聚、低耦合
父组件:
- 属性:当前选中的节点、容器方向、容器背景颜色 子组件:
- 属性:当前步骤状态,激活、未激活、完成状态图标/颜色、标题
- 方法:组件的点击事件
- 扩展:图标插槽、标题插槽
A8:懒加载、预加载的应用场景
解答:
懒加载:
- 图片/视频:更换图片的url地址;(
Element.getBoundingClientRect()方法返回元素的大小及其相对于视口的位置。) - 组件:加载条件为 v-if, 可以使用骨架组件来过渡
- 路由:import方法
const HelloWorld = ()=>import('需要加载的模块地址')
预加载:对于大型页面, 如果未使用预加载会出现短时间的白屏;自定义字体,会出现文字闪动;视频播放, 自动缓存下一集。
A9:Nuxt.js 是什么,什么场景用
解答:
什么是Nuxt.js?
是一个基于 Vue.js 的轻量级应用框架,可用来创建服务端渲染 (SSR) 应用,也可充当静态站点引擎生成静态站点应用,具有优雅的代码结构分层和热加载等特性。
优点:
- 代替浏览器的工作,笼统理解就是在created时的请求数据和页面渲染
- 当作静态文件服务器,把渲染好的页面 返回给用户。
缺点:
- 由于资源请求量大,造成网站首屏加载缓慢,不利于用户体验。(增加服务端工作量)
- 由于页面内容通过js插入,对于内容性网站来说,搜索引擎无法抓取网站内容,不利于SEO。
解答:A10
A12:皮肤切换怎么实现
解答:
- theme:定义
theme参数,通过prop下发,子组件根据theme来动态绑定style的方式实现。 - link:切换css地址 / 文件
- 类选择器:给所有
css选择器加一个样式名的类选择器,并把这个类名绑定到body元素上,然后通过DOM API来动态切换主题。
A13:地图上的图标过多时候怎么处理
解答:
多个标注点标注:
点不多时候:
- 在初始化地图后,添加
this.addMarker();//添加设备标注到地图
addMarker(){
var myIcon=null;
for (let i=0; i < this.devInfo.length; i++) {
let point = new BMap.Point(this.devInfo[i].longitude, this.devInfo[i].latitude);
myIcon = new BMap.Icon(require('../assets/imgs/grey.png'), new BMap.Size(22,32));
let marker = new BMap.Marker(point,{icon:myIcon});
this.map.addOverlay(marker);//将标注添加到地图中
}
}
- 聚合点, 批量加入
addMarker(){
let markers = [];//点聚合BMapGLLib
devInfo.forEach((item,index)=>{//创建自定义标记点
if(!item.latitude){
console.log(item,'这个点无经纬度,造成地图marker错误')
}
let point = new BMap.Point(+item.longitude,+item.latitude);
let myIcon = new BMap.Icon(require('../assets/imgs/grey.png'), new BMap.Size(22,32));
let marker = new BMap.Marker(point,{icon:myIcon});
this.points.push(point)
markers.push(marker)
})
let markerClusterer = new BMapLib.MarkerClusterer(this.map, {markers:[]});
markerClusterer.addMarkers(markers)
}
详解:vue--百度地图之离线地图--大量标注点造成卡顿问题--海量点聚合性能优化
A15:什么是宏任务 / 微任务? 哪些属于宏任务 / 微任务?
解答:
什么是 宏任务/ 微任务:
- 宏任务执行过程中可以临时加上一些额外需求,这些额外的需求有两种处理方案:第一种是可以选择作为一个新的宏任务进到队列中排队,第二种就是可以作为当前任务的【微任务】。
- 微任务指的是在当前任务结束过后立即执行。
- 微任务是后来才加入到 js 中的,就是为了提高整体的响应能力。
哪些属于 宏任务/ 微任务:
- Promise 的回调会作为微任务执行,所以会在本轮调用的末尾去自动执行。而 setTimeout 是以宏任务的形式进入到回调队列的末尾。
- 目前绝大多数异步调用都是作为宏任务执行。而 Promise、MutationObserver、process.nextTick 是会作为微任务在本轮任务末尾执行的。
解答:A15