-
数据类型
分两大类共八种数据类型,基本类型有Number,String,Boolean,BigInt,Undefined,Null,Symbol七种,复杂类型只有Object一种。基本类型存值于栈中,复杂类型存址于栈中,址为堆中数据的地址引用。 -
数组的常用方法
//// 增
// push()接收任意数量的参赛,添加到数组末尾。返回数组长度
push()
let colorList = []
colorList.push('red', 'green')
// unshift()接收任意数量的参赛,添加到数组头部。返回数组长度。
unshift()
colorList.unshift('blue')
// splice()可实现增删改。传入起始位置,删除的个数,任意数量个插入的参赛。
splice(1, 0, 'yellow', 'pink')
// concat()创建一个当前数组的副本,将参赛添加到副本后,返回新的数组。参赛可以是单个元素,也可以是数组。
concat()
//// 删
pop() // 对应push(),从末尾删除一个。
shift() // 对应unshift(),从开头删除一个。
splice() // splice(1, 50),第二个参赛表示从起始位置开始删除的项目个数。
slice() // slice(start, end),截取数组的一部分,返回这部分,不会改变原数组。左闭右开。
//// 改
splice() // 删除后再插入新的,实现改。splice(1, 1, 'lzq')
//// 查
indexOf() 查找元素在数组中的位置
includes() 查找是否包含某个元素
find() 查找某个元素
//// 排序方法
sort()
reverse() 反转
//// 转换方法
join() 转换成字符串
//// 迭代方法
map()
forEach()
some()
every()
filter()
reduce()
- 字符串的常用方法
//// 增
concat() // 连接
//// 删 (创建一个新的子字符串)
substr(strat, length)
substring(start, end)
slice(start, end)
//// 改
trim() // 去除两边空格
trimLeft()
trimRight()
repeat() // 重复
padEnd()
padStart() // 复制字符串,如果小于给定的长度,在对应的一边填充字符
toLowerCase()
toUpperCase() // 大小写转换
//// 查
indexOf()
charAt()
startWidth()
includes()
//// 转换方法
split() 转换成数组
//// 正则匹配
match()
search()
replace() // 匹配替换
- 类型转换 分为显式转换和隐式转换。当进行比较运算和算数运算且操作符两边类型不同时,会进行隐式转换。
// 常见的显示转换方法
Number()
parseInt()
Boolean()
String()
- ==和===的区别
==是等于操作符,会先进行类型转换再比较是否相等。
===是全等操作符,不会进行类型转换。需要类型相同,值也相同。
等于操作符的隐式类型转换:
1、都为简单类型,字符串和布尔值转换成数值比较。
2、简单类型于引用类型,引用类型先转换成普通类型。
3、都为引用类型,判断是否指向同一个对象。
4、null 和 undefined 相等。
5、存在NaN返回false
- 浅拷贝与深拷贝
- 浅拷贝只拷贝一层,深层的引用依然复制地址,共享内存。
- 深拷贝是递归拷贝每一层。深层的引用也重新分配内存拷贝。
// 手写深拷贝
const cloneDeep = (obj) => {
if(Object.toString.call(obj) === '[object Array]' || Object.toString.call(obj) === '[object Object]') {
let newObj
for(let key in obj) {
if(obj.hasOwnProperty(key)){
newObj[key] = cloneDeep(obj[key]) // 递归
}
}
return newObj
}
return obj
}
-
闭包
闭包是能够读取其他函数内部变量的函数。
闭包可以用来模拟私有变量或延长变量的生命周期。 -
作用域链 作用域是指有权访问的变量集合。有全局作用域,函数作用域,块级作用域。且是逐层嵌套的。当我们访问变量时,会首先在当前作用域寻找,如果没有就逐层往上寻找,直到找到或到达全局作用域返回undefined。这就是作用域链的表现。
-
原型链
每一个对象都有一个原型,指向其构造函数的原型对象,这个原型对象也是一个对象,也有一个原型,指向其构造函数的原型对象,这样就形成了原型链。
原型链的终点是null
-
javascript的继承
-
VUE 双向绑定的原理 VUE使用数据劫持和发布订阅模式实现数据的双向绑定,使用
Object.defineProperty()劫持属性的setter/getter,数据变化时发布订阅给订阅者,调用对应的方法更新视图。有三个重要的组成部分,observer监听器、compile解析器、watcher观察者。监听器劫持属性的变化通知观察者调用对应的方法更新视图。解析器解析节点的指令和属性,绑定对应的更新函数,当视图改变时通知观察者调用更新函数更新数据。 -
VUE的生命周期 常用的主要有创建前后、挂载前后、更新前后、销毁前后。
beforeCreate: // 初始化
created: // 用于获vue
取异步数据
beforeMount:
mounted: // 已经创建了dom,可以获取dom。
beforeUpdate: // 更新前,可以拿到更新前的状态
updated: // 更新后,可以拿到最新的状态
beforeDestroy:
destroyed:
-
react的key的作用。
key是react对组件的唯一标识。在diff算法中,用于判断元素是否需要重新创建,优化react渲染性能。 当key重复时,会有对应的报警。此时更新数据触发dom更新,可能会有显示bug。从页面上来看可能会多几项,是因为react在删除之前的dom节点时,先在虚拟dom中通过key去查找,会导致多个节点因为key一样,拿到的需要删除的真实dom节点是同一个,导致删除不完全。 -
虚拟dom的实现原理。
虚拟dom是对真实dom的抽象和描述,本质是一个js对象。我们对页面进行操作的时候,会频繁的修改dom,而修改dom会触发回流重绘,成本较大。虚拟dom就是将一组dom操作,先生成新的虚拟dom,再用diff算法和之前的虚拟dom进行比较,找到最小的差异,再进行真实dom操作,一次性修改,减少回流重绘。整个操作是以js对象为基础,比操作真实dom成本要小很多。 -
vue3的新特性