js基础
变量提升/函数声明提升
函数声明优先级最高,会覆盖同名变量
代码在编译阶段会先进行变量和函数的声明提升的操作
作用域
全局作用域
函数作用域
块作用域
作用域链
this指向
new生成新对象
call/apply/bind 绑定this
函数对象的方法调用
默认绑定全局
隐式转换
引用类型先转成基本类型
数组转成元素拼接的字符串
对象转成'[object Object]'<br>
原型链
构造函数的prototype指向原型对象
原型对象的constructor指向构造函数
构造函数的实例的__proto__指向原型对象<br>
new的实现
生成一个空对象
空对象的proto指向构造函数的原型对象 Object.setPrototypeOf(obj, fn.prototype)<br>
this指向新对象
执行构造函数的代码
返回新对象
浏览器的事件循环机制
宏任务
同步代码
setInterVal/setTimeout<br>
I/0操作<br>
用户的交互事件
微任务
promise.then
mutationObserver<br>
箭头函数
继承外层作用域的this
不能当作构造函数
没有arguments对象
没有原型属性
垃圾回收
堆
新生代
存放小的以及存活时间短的对象
活动区域
空闲区域
两者交替
map和object的区别
object的key只能是字符串和symbol;map的key可以是任意类型
object的key的数量需要手动计算;map可以通过size获取
object只能用for in循环;map可以通过for of
map适用于需要频繁对key进行增删的场景。object不适合
map和weakMap的区别<br>
weakMap的key只能是对象,且是弱引用的,如果检测到没有被引用,就会自动回收<br>
map的key可以是任何类型,需要手动回收
promise
概念
异步编程的解决方案
解决了回调地狱的问题
有三个状态:进行中/已完成/已拒绝<br>
任务完成了就是从进行中到已完成;失败了就是从进行中到已拒绝
一旦状态改变就不能再更改为其他状态
无法取消
通过resolve和reject来改变状态
通过then可以链式调用
all
都成功返回结果数据,有一个失败只返回失败的结果
allSettled<br>
等待所有promise完成,并返回结果数组
内存泄漏
闭包
定时器
引用dom的变量
全局变量
console.log
proxy 和 reflect
为什么要结合使用
需要reflect的reviver传递正确的执行上下文,保证this的正确指向
esModule和commonJS<br>
commonJs输出的是值的拷贝,输出之后,模块内部的改变不会再影响已经输出的值<br>
esModules输出的是值的引用,当读取值的之后才去module内读取值,如果module内部改变了值,会影响到外面的引用<br>
vue
响应式原理
初始化阶段劫持数据设置getter和setter
渲染阶段,读取数据,触发getter,生成watcher实例,加入到dep
更新阶段,修改数据,触发setter,遍历dep,挨个触发watcher<br>
vue3的升级
响应式处理
vue2: object.defineProperty<br>
无法监听对象key的增删
vue3: proxy<br>
性能的提升
响应式数据的处理
vue2在初始化的时候需要递归处理data中所有的数据
vue3基于proxy实现的ref/reactive在运行时
diff算法
vue2
头头对比
头尾对比
新增新列表中未遍历到的节点
删除老列表中未遍历到的节点
vue3
标记静态元素
头头对比 尾尾对比
找出最长递增子序列
处理剩下的节点
setup
隐藏了beforeCreate和created声明周期<br>
生命周期
onBeforeMount<br>
onMounted<br>
onBeforeUpdate<br>
onUpdated<br>
onBeforeUnmount<br>
onUnmounted<br>
onActiveted<br>
onDeactiveted<br>
vue3
ref 和 reactive的区别
读取方式
ref需要.value
reactive不需要
for what
ref for 基本类型数据 也可复杂类型
reactive 复杂类型数据 only
实现原理
reactive
proxy对传入的数据进行响应式包装
ref
首先用reactive包装了一层,增加 value 属性,然后proxy监听value 属性
watch和watchEffect的区别<br>
watch
声明依赖对象
可以拿到oldValue<br>
默认初始化不会执行
immediate:true 就会先执行<br>
watchEffect<br>
不需要声明依赖对象
拿不到oldvalue
初始化就会执行
设置flush:post可以更新之后的dom 或者 watchPostEffect<br>
组件通信
props / emit
provide/inject
vueX/pinia<br>
expose/ref
性能优化
包体积优化
tree shaking
使用支持es模块的依赖
defineAsyncComponent 组件懒加载<br>
代码层面
props稳定性
v-once
v-memo
computed 稳定性
大型数据的稳定性
shallowRef/shallowReactive 只做浅层的响应式处理<br>
不必要的组件抽象
hash 和 history的区别
hash
有个#<br>
onhashChange
hash值不会出现在请求中
history
没有#<br>
pushState/replaceState<br>
刷新后,服务端没有对应配置会404
react
diff算法
同层级diff
遍历新旧列表,遍历结束处理剩下的节点
fiber架构
requestIdleCallback<br>
时间分片:利用浏览器空闲时间执行任务<br>
双缓冲机制
维护两颗fiber树。交替更新保证连续性
hook为什么不能写在条件语句
底层将所有hook串成了一个链表
usecallback / useMemo<br>
useMemo 处理值
useCallback 处理函数
useLayoutEffect<br>
页面渲染前执行
useState和useRef的区别<br>
useState的数据必须通过setState修改,是异步的,会触发页面更新,每次渲染都是独立的<br>
useRef:在current中直接修改,是同步的,不会触发页面更新<br>
组件通信
props
子组件用forwardRef包裹,通过useImperativeHandle暴露方法,父组件通过ref调用<br>
逻辑/状态复用
自定义hook
状态提升
context
redux
触发重新渲染的条件
被父组件连带更新
props变化
setState<br>
消费的context变化
react的并发模式
fiber的可中断渲染
过渡更新
startTranstion和useTranstion 标记非紧急更新,不阻塞交互<br>
性能优化
useMemo/useCallback<br>