5.17面试

109 阅读6分钟

1. 父子组件创建的过程

创建过程自上而下, 挂载过程自下而上, 父组件创建=> 子组件创建=>子组件挂载=>父组件挂载,   因为vue创建是一个递归的过程, 子组件首次创建会添加mounted钩子到任务队列, patch结束后会先执行

1. 跨域

浏览器的同源策略策略导致跨域, 限制一个源的文件或者加载的脚本去与另一个源的资源进行交互, 是一个用于隔离潜在恶意文件的重要机制,  jsonp(通过script标签的src属性,请求跨域的数据接口,并通过函数调用的形式,接收跨域接口响应的数据),  cors 解决跨域(跨站资源共享(请求头,请求方式,响应头)) ,反向代理 (代理服务器, 服务器根据客户端的请求,从其关系的一组或多组后端服务器(如Web服务器)上获取资源,然后再将这些资源返回给客户端,)

2. v2 v3 响应式数据原理

当我们修改数据的时候, 页面随之更新,  

vue2通过object.defineproperty实现数据劫持 ,对属性进行递归监听,  

通过getter触发则进行依赖搜集( 创建Dep 对象用于依赖收集,Dep.target, 它实现了一个发布订阅模式,完成了数据 Data 和渲染视图 Watcher 的订阅 ) 

通过 setter 触发进行派发更新( 当数据 Data 变化时,调用 Dep.notify 方法,通知所有使用到这个 Data 的 Watcher 对象,  如果同一个 watcher 被多次触发,只会被推入到队列中一次。 开启一个异步队列,并缓冲同一事件循环中发生的所有数据变更。然后执行 render 方法生成新的虚拟DOM, 通过新旧DOM对比, 执行patch函数,  完成页面更新。 )

通过数据代理直接获取_data身上的数据,    

通过重写更新数组的7个方法(push、pop、shift、unshift、splice、sort、reverse)来实现拦截, 一部分实现原生方法, 一部分实现更新数据(考虑性能放弃了对数组劫持), 存在新增熟悉 , 删除属性,及通过数组下标修改数组, 页面不会更新问题, 需要调用$set/delete方法, 

vue3针对基本数据类型, ref 使用还是object.defineproperty ,进行数据劫持的getter和setter来实现响应式, reactive 通过使用Proxy 来对整个对象进行劫持, 并通过reflect操作源对象内部的数据

  • Object.defineProperty 并非不能监控数组下标的变化,vue2.x中无法通过数组索引来实现响应式数据的自动更新是vue本身的设计导致的,不是 defineProperty 的锅。
  • Object.defineProperty 和 Proxy 本质差别是,defineProperty 只能对属性进行劫持,所以出现了需要递归遍历,新增属性需要手动 Observe 的问题。
  • Proxy 作为新标准,浏览器厂商势必会对其进行持续优化,但它的兼容性也是块硬伤,并且目前还没有完整的polifill方案。

3. 为什么使用uni-app, 如何设置请求根路径?

平台能力不受限: 开发一次, 多端覆盖

性能体验优秀: 加载新页面速度更快、自动diff更新数据。

周边生态丰富: 数千款插件, 支持NPM、支持小程序组件和SDK。

学习成本低/开发成本低: 基于通用的前端技术栈,采用vue语法+微信小程序api,无额外学习成本。

使用uni.addInterceptor('request', OBJECT)方法, 添加拦截器: 拦截request请求\ 拦截uploadFile文件上传

  1. 基础地址
  2. 超时时间
  3. 请求头标识
  4. 添加 token

4. 原型链的继承

基于原型对象的继承, 使得不同构造函数的原型对象相互关联起来, 这种关联的关系是一种链状的解构, 称为原型链

原型: 构造函数通过原型分配的函数 ,是所有对象所共享的, 这个对象上可以挂在函数, 对象实例化不会多次创建原型上的函数, 节约内存, 构造函数和原型对象中的this都指向实例化对象

new实例化的过程 1.创建一个新对象, 2.构造函数里的this指向这个新对象3. 为这个对象添加属性和方法 4. 

原型链的查找机制: 当查看这个对象的属性和方法时, 首先查找这个对象自身, 如果没有就查找这个对象的原型(也就是__proto__指向的原型对象), 如果还没有就查找原型对象的原型, 一直找到object(null)为止,  对象原型的意义在于为对象成员的查找机制提供一个方向, 或者是一条路线

instanceof运算符用于检测构造函数的prototype是否出现某个实例对象的原型链上

5. 作用域

全局作用域(script标签和.js文件最外层), 局部作用域(函数作用域, 块作用域) 

作用域链的本质是底层变量的查找机制 , 函数执行时会优先从当前作用域中查找变量, 当前作用域查找不到, 会一次逐级查找父级作用域直至全局作用域

6. 闭包

概念: 一个函数对周围状态的引用捆绑在一起,内存函数中访问其外层作用域

简单理解: 内层函数加外层函数的变量, 

作用: 封闭数据, 提供操作, 外部也可以访问函数内部的变量

缺点: 容易造成内存泄漏 , 不再用到的内存,没有及时的释放,就叫内存泄漏

两种垃圾回收算法: 

引用计数法: 跟踪每个值被引用的次数, 引用+1, 减少一个引用-1, 引用为0,释放内存, 存在致命问题嵌套引用

标记清除法: 将不再使用的对象定义为无法达到的对象, 那些无法有根部触发触及到的对象标记为不再使用, 善后进行回收

7. promise

8. uniapp项目数据是如何更新的,更新流程是什么

9.  uniapp项目有没有遇见兼容性问题,如何解决的

10. 微信支付

1. 用户平台下单, 发起支付, => 商户系统后台 2.生成平台订单, 3.请求下单接口,创建订单() =>**微信支付系统,**4.生成预付单 ,  5. 返回预付单标识,  => 商户系统后台 , 6. 生成带签名支付信息

7. 用户发起支付=>商户系统后台8. 调起微信支付=> 微信客户端 9. 发起支付请求=>微信支付系统10验证支付授权权限,11返回支付授权 => 微信客户端

12 用户确认支付, 输入密码 => 微信客户端 13提交授权=>微信支付系统 14 验证授权

11.  vue-router 动态路由

router.addRoutes 方法可以为 Router 实例动态添加路由规则,

12.  git协作如何进行

Git可以完成两件事情:1.版本控制  2.多人协作开发