1. [] == true
2. 数组相关api (至少28个)
栈方法和队列方法4
- push()
- pop()
- unshift()
- shift()
重排序方法2
- sort() 调用每个数组项的 toString()转型方法,比较的是字符串
- reverse()
操作方法12
- concat()
- join()
- slice() 基于当前数组中的一或多个项创建一个新数组
- splice() 向当前数组的中部插入项 删除 插入 替换,操作当前数组
- flat() 将嵌套的数组“拉平”,变成一维的数组,返回一个新数组,对原数据没有影响
- flatMap() 方法对原数组的每个成员执行一个函数,对返回值组成的数组执行flat()方,返回一个新数组,对原数据没有影响
- Array.from() 将类数组转为真正的数组
- Array.isArray() 是否是数组
- Array.of() 方法用于将一组值,转换为数组
- toString() 以逗号分隔的字符串
- valueOf() 还是数组
- length()
位置方法5
- indexOf()
- lastIndexOf()
- find()
- findIndex()
- includes()
迭代方法8
- every()
- some()
- map() 返回每次函数调用的结果组成的数组
- forEach() 没有返回值
- filter() 返回该函数会返回 true 的项组成的数组
- keys()
- values()
- entries()
归并方法2
- reduce()
- reduceRight()
3. flex
Flex布局有两层,采用flex布局的元素称为flex容器,其子元素则自动成flex item,即项目.
注:flex不同于block,flex容器的子元素的float,clear,vertical-align属性将失效.
Flex布局:
flex容器有两根轴:水平主轴就是x轴(main axis)和竖直轴也是y轴(cross axis),两轴相关位置标识如下:
flex容器属性:
-
flex-direction:决定项目的排列方向。
-
flex-wrap:即一条轴线排不下时如何换行。
-
flex-flow:是flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap。
-
justify-content:定义了项目在主轴上的对齐方式。(justify)
-
align-items:定义项目在交叉轴上如何对齐。
-
align-content:定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。(换行会产生多轴)
Flex item属性:
-
order:定义项目的排列顺序。数值越小,排列越靠前,默认为0。
-
flex-grow:定义项目的放大比例,如果所有项目的flex-grow属性都为1,则它们将等分剩余空间(如果有的话)。如果一个项目的flex-grow属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍。
-
flex-shrink:定义了项目的缩小比例,默认为1,如果所有项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小。如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小。
-
flex-basis:定义了在分配多余空间之前,项目占据的主轴空间(main size)。
-
flex:是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto。后两个属性可选。
-
align-self:允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。
display: flex;
flex: flex-grow flex-shrink flex-basis;
justify-content: center;
align-items: center;
解释执行过程
函数执行过程时会创建执行上下文,而执行上下文的创建分为两个阶段:创建阶段和执行阶段。
创建阶段:
- 作用域
- 变量提升、函数提升、定义参数
- 指定this
执行阶段:
- 变量赋值
- 函数执行
ES6 规定暂时性死区和let、const语句不出现变量提升,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。
作用域
全局作用域、函数作用域、块级作用域,是在执行上下文的创建阶段生成的。全局作用域 -> 函数作用域 就形成了作用域链。
函数自身 => func.prototype => func.proto => func.proto.prototype => func.proto.proto.prototype
闭包
一个函数可以调用另一个函数中的变量或方法
function outer() {
let name = 'heihei'
let inner = function () {
console.log(name)
}
return inner
}
outer()
outer()()
手写bind
{
}
跨域
缓存
https
vue原理性的概念
依赖收集
https://www.zhihu.com/search?q=%E4%BE%9D%E8%B5%96%E6%94%B6%E9%9B%86&type=content
所以在getter里,我们进行依赖收集(所谓依赖,就是这个组件所需要依赖到的数据),当依赖的数据被设置时,setter能获得这个通知,从而告诉render()函数进行重新计算
使用的观察者模式:
- 依赖的数据是观察目标
- 视图、计算属性、侦听器这些是观察者
defineReactive
Vue源码中实现依赖收集,实现了三个类:
- Dep:扮演观察目标的角色,每一个数据都会有Dep类实例,它内部有个subs队列,subs就是subscribers的意思,保存着依赖本数据的观察者,当本数据变更时,调用dep.notify()通知观察者
- Watcher:扮演观察者的角色,进行观察者函数的包装处理。如render()函数,会被进行包装成一个Watcher实例
- Observer:辅助的可观测类,数组/对象通过它的转化,可成为可观测数据
配置依赖观测
收集依赖
数据值变更
Object.defineProperty(o, "b", {
get : function(){
return bValue;
},
set : function(newValue){
bValue = newValue;
},
enumerable : true,
configurable : true
});
computed
在使用层面:是一个可以依赖多个属性通过一系列的计算得到一个新值;
比如说我们有这样一个业务场景就很适合computed;
我们有个支付页,支付页上有些固定金额可以任意点击,还有一些附加保险可以选择,任意一处用户操作了,都需要从新计算总金额;所以总金额就可以使用computed 依赖(固定金额 + 保险金额)其实它的内部实现也使用了观察者模式进行了依赖收集。
diff key
diff算法只vue中为了处理虚拟dom,减少性能损耗添加的,
diff算法的比较原则是:zhuo层比较,每个vnode节点上都有key属性,首先根节点确定,比较第二层的时候
旧虚拟dom 新虚拟dom
开始节点 结束节点 开始节点 结束节点
开始节点id 结束节点id 开始节点id 结束节点id
旧虚拟dom开始节点 与 新虚拟dom结束节点对比
两两比较 4个比较规则,之后
基本规则:先移动、删除、插入,新插入的vnode节点需要给他加上key,方便后边后续再更新 进行diff算法比较
异步更新队列
如果同一个 watcher 被多次触发,只会被推入到队列中一次。nextTick
vue3.0新特性
vue3.0的设计目标
更小
更快
加强TypeScript支持
加强API设计一致性
提高自身可维护性
开放更多底层功能
- 压缩包体积更小: 20Kb -> 10kb
- Object.defineProperty -> Proxy
- 3,Virtual DOM 重构
proxy
Object.defineProperty -> Proxy
拦截对象对象属性 》对象(颗粒度)
数组的setter检测有问题
动态在data根上变更属性检测不到
网友评论