异步
什么是单线程,和异步有什么关系
单线程,只有一个线程,同一时间只能做一件事,两段 JS 代码不能同时执行
原因,避免 DOM 渲染的冲突
- 浏览器需要渲染 DOM
- JS 可以修改 DOM 结构
- JS 执行的时候,浏览器 DOM 渲染会暂停
- 两段 JS 也不能同时执行(都修改 DOM 就冲突了)
- webworker 支持多线程,但是不能访问 DOM
解决单线程方法:异步
- 问题一:没按照书写方式执行,可读性差
- 问题二:callback 中不容易模块化
什么是 event-loop
- 事件轮询,JS 实现异步的具体解决方案
- 同步代码,直接执行
- 异步函数先放在 异步队列 中
- 待同步函数执行完毕,轮询执行 异步队列 的函数
是否用过 jQuery 的 Deferred
Deferred 延迟
jQuery 1.5 之前
// 修改开发扩展封闭 |
jQuery 1.5 及之后
const ajax = $.ajax('data.js') |
// 很像 Promise 的写法 -- 扩展开发修改封闭 |
jQuery 1.5 的变化
- 无法改变 JS 异步和单线程的本质
- 只能从写法上杜绝 callback 这种形式
- 它只是一种语法糖形式,但是解耦了代码
- 很好的体现:开放封闭原则
使用 jQuery Deferred
不使用
const wait = () => { |
使用
成功
function waitHandler (){ |
失败
function waitHandler (){ |
但在 const w = waitHandler() 可以直接调用 w.reject() 会导致后面的结果出现偏差
function waitHandler (){ |
Promise 的基本使用和原理
加载一张图片
function loadImg(src) { |
加载第一张后再加载第二张
function loadImg(src) { |
普通
img1.then(img1 => { |
使用 Promise.all()
Promise.all([img1, img2]).then(res => { |
使用 await/async
function loadImg(src) { |
介绍一下 async/await(和 Promise 的区别、联系)
- 不是取代 Promise 的,而是对 Promise 的补充
- 使用了 Promise,并乜有和 Promise 冲突
- 使用 await,函数必须用 async 标识
- await 后面跟的是一个 Promise 实例
- 完全是同步的写法,再也没有回调函数
- 但是:改变不了 JS 单线程、异步的本质
总结一下当前 JS 解决异步的方案
- jQuery deferred
- Promise
- async/await
- Generator
- 不是异步的直接替代方式
原型
说一个原型的实际应用
- 描述 jquery 如何使用原型
- 描述 zepto 如何使用原型
- 结合自己的开发经验,其中使用的原型
原型如何体现它的扩展性
- 说一下 jquery 和 zepto 的插件机制
- 结合自己的开发经验,做过的基于原型的插件
vdom、虚拟 dom、virtual dom
- vdom 是 vue 和 react 的核心
- 如果面试问道 vue 和 react 和实现,免不了问 vdom
vdom 是什么?为何会存在(为何使用) vdom?
虚拟 DOM
用 JS 模拟 DOM 结构
DOM 变化的对比,放在JS 层来做(图灵完备语言)
提高重绘性能
DOM 操作是“昂贵”的,JS 运行效率高
劲量减少 DOM 操作,而不是“推到重来”
项目越复杂,影响就越复杂
vdom 可以解决
vdom 如何应用,核心 API 是什么
- 如何使用?可用 snabbdom 库的用法举例
- 核心 API:h 函数、patch 函数
- vdom-snabbdom 使用 vdom 实现的一个库
- h(‘<标签名>’, {…属性…}, […子元素…]) –> 有很多子元素
- h(‘<标签名>’, {…属性…}, ‘…’) –> 只有一个文本节点的子元素
- patch(container, vnode) –> 将 节点 添加到容器中,初次渲染
- patch(vnode, newVnode) –> 新旧节点对比,将需改的内容添加,再次渲染
介绍一下 diff 算法
- 什么是 diff 算法
- 去繁就简
- diff 算法非常复杂,实现难度很大,源码量很大
- 去繁就简,讲明白核心流程,不关心细节,
- 2、8原则:
- 学习的东西太多了,现在不能一行一行的学习,根据目录去查找自己需要补充的重点,然后纤细去看那部分,余下部分过一遍就行。
- 面试官也大部分不清楚细节,但是很关心核心流程
- vdom 为何用 diff 算法
- DOM 操作是“昂贵”的,因此劲量减少 DOM 操作
- 找出本次 DOM 必须更新的节点来更新,其他的不更新
- 这个“找出”的过程,就需要 diff 算法
- vdom 中应用 diff 算法是为了找出需要更新的节点
- diff 算法的实现流程
vue
看视频、看博客、看文章都属于看源码,并不是非要去看代码才算看源码
说一下使用 jQuery 和使用框架的区别(vue、react)
代码演示、使用总结
数据与视图的分离,解耦(开放封闭原则)
以数据驱动视图,只关心数据变化,DOM 操作被封装
说一下对 MVVM 的理解
先讲 MVM 再讲 MVVM
MVC:
- Model(数据)、View(视图、界面)、Controller(控制器、逻辑处理)
- 用户 –> View –> Controller –> Model(View 发生变化出发 Conatroller,Controller 修改 Model,Model 导致 View 更新)
- 用户 –> Controller –> Model –> View
MVVM
- Model(模型、数据)、View(视图、模板)、ViewModel(桥梁,连接 Model 和 View)
- 视图和模型是分离的
- MVVM 不算一种创新,是在 MVC 上的一种微创新
- 但其中的 ViewModel 确是一种创新
- 真正结合前端场景应用的创建
MVVM 框架的三要素
响应式:vue 如何监听到 data 的每个属性变化?
模板引擎:vue 的模板如何被解析,指令如何处理?
渲染:vue 的模板如何被渲染成 html?以及渲染过程
vue 中如何实现响应式?
- 关键是理解 Object.defineProperty
- 讲一下 data 的属性代理到 vm 上
什么是响应式?
- 修改 data 属性后,vue 立刻监听到
- data 属性被代理到 vm 上
Object.defineProperty() 如何使用?在 vue 中如何使用?
模拟、演示
vue 中如何解析模版?
模版是什么
模版最终必须转化为 JS 代码,因为:
有逻辑(v-if v-for),必须用 JS 才能实现(图灵完备)
转换为 html 渲染页面,必须用 JS 才能实习
因此,模板后需要转换成一个 JS 函数(render 函数,渲染函数)
模板:字符串,有逻辑,嵌入 JS 变量…
模板必须转换为 JS 代码(有逻辑、渲染 html、JS 变量)
with 的用法(劲量不要用,render 函数用到了,会给开发调试带来很大的成本)
读一读《js语言精粹》美国比较牛的js程序员写的,js创始人,有价值,有干货
render 函数
- 哪里可以看到 render 函数?– 在 vue.js 源码中搜索 render,在 code.render 中可以看到
- render 函数是什么样子的?
- v-if v-for v-on 都是怎么处理的?
- vm._c是什么?render 函数返回了什么?
- render 函数执行返回 vnode
render 函数与 vdom
如何解析模版
vue 的整个实现流程
- 解析模板成 render 函数
- 模板中的所有信息都被 render 函数包含
- 模板中用到的 data 中的属性,都变成了 JS 变量
- 模板中的 v-model v-for v-on 都变成了 JS 逻辑
- render 函数返回 vnode
- 响应式开始监听
- 使用 Object.defineProperty()
- 将 data 的属性代理到 vm 上
- 首次渲染,显示页面,且绑定依赖
- 初次渲染,执行 updateComponent,执行vm._render()
- 执行 render 函数,会访问到 vm.list 和 vm.title
- 会被响应式的 get 方法监听到
- 执行 updateComponent,会走到 vdom 的 patch 方法
- patch 将 vnode 渲染成 DOM,初次渲染完成
- 为何要监听 get,直接监听 set 不行吗?
- data 中有很多属性,有些被用到,有些可能不被用到
- 被用到的会走 get,不被用到的不会走到 get
- 未走到 get 中的属性,set 的时候我们也无需关心
- data 属性变化,触发 rerender
- 修改属性,被响应式的 set 监听到
- set 执行 updateComponent
- updateComponent 重新执行 vm.render()
- 生成的 vnode 和 preVnode,通过 patch 进行对比
- 渲染到 html 中