1.深拷贝和浅拷贝(js)
为什么要用深拷贝和浅拷贝
同一个Array或者Object赋值给两个不同变量时,变量指向的是同一个内存地址,所以就会造成其中一个变量改变属性值,同时改变了另外一个变量的对应属性值。如果我们想要的结果是两个变量(初始值相同)互不影响。所以就要使用到拷贝(分为深浅两种)
如果对象只有一层,就可以用浅拷贝,如果对象有多层,就是对象的属性又是一个对象,就需要用深拷贝
浅拷贝
const obj = {
a: 1,
goods: { name: '鞋', price: 199 }
}
const b = { ...obj }
b.goods.name = '球鞋'
方法
- {...obj}
- Object.assign({},obj)
深拷贝
- JSON.parse(JSON.stringify(obj))
JSON.parse(JSON.stringify(obj))有缺点,当对象有方法的时候,方法会丢失 - 递归
如果对象身上有方法,需要用递归 - lodash
1.下包 yarn add lodash
2.引入 import lodash from 'lodash'
3.实现拷贝 const obj1 = lodash(obj)
【不管数据对象有多少层,改变拷贝后的值都不会影响原始数据的值】 (拷贝后的数据与原始数据毫无关系)
2.substr和substring的区别(js)
相同点
substring 和 substr都是对字符串进行截取
不同点
substr
substr() 方法可在字符串中抽取从start下标开始的指定数目的字符串
语法:str.substr(start(开始的索引),length(长度))
说明:start参数可以是任意整数,如果是负数,则从str的尾部开始算起
var str = 'abcde leodonna'
console.log(str.substr(8)) //odonna
console.log(str.substr(-4)) //onna
console.log(str.substr(4,4)) //e le
console.log(str.substr(-3,6)) //nna
substring
substring() 方法截取str从start到end的所有字符(包含起始位置,但不包含结束位置)
语法:str.substring(start,end)
说明:如果未指定end参数,则截取从start到原字符串结尾的字符串
var str = 'abcde leodonna'
console.log(str.substring(1,8)) //bcde le
console.log(str.substring(4)) //e leodonna
console.log(str.substring(4,1)) //bcd
3.slice和splice的区别(js)
相同点
slice 和 splice 都是对 【数组】 进行截取。
不同点
slice
slice 方法可从已有数组中返回选定的元素,返回一个新数组
语法:slice(start,end),不改变原数组,返回新数组
参数:
- start: 必需。起始元素,使用负数可从数组结尾处规定位置。
- end:可选。截止元素
var arr = [1, 2, 3, 4, 5]
console.log(arr.slice(1, 3)) //截取的[2,3]
console.log(arr);// 数组不变[1, 2, 3, 4, 5]
splice
splice 方法可从数组中添加或者删除项目,返回被删除的项目。
语法:splice(index, howmany, item1, …, itemX),会改变原数组,从某个位置开始删除多个元素,并可以插入新的元素。
参数:
- index: 必需。整数,规定添加/删除项目的位置,使用负数可从数组结尾处规定位置。
- howmany:必需。要删除的项目数量。如果设置为 0,则不会删除项目。
- item1, …, itemX: 可选。向数组添加的新项目。
var arr = [1, 2, 3, 4, 5]
console.log(arr.splice(1, 3, 'hello')) //删除的[2,3,4]
console.log(arr);//改变原数组[1,"hello", 5]
4.事件循环——宏任务和微任务(js)
宏任务与微任务表示异步任务的两种分类
微任务
由 javascript 自身发起的异步:微任务
Promise async/await
宏任务
由宿主环境发起的异步:宏任务
setTimeout setInterval setImmediate Ajax DOM事件
js是单线程语言,同一时间只能做一件事。这就使得后面的任务要等前面的任务,如果前面的任务太大,后面的就要一直等下去。于是为了解决这个问题js出现了同步任务和异步任务
同步和异步的区别:
异步不会阻塞程序的执行,同步会阻塞程序的执行
同步任务:
在主线程上排队执行的任务只有前一个任务执行完毕,才能执行后一个任务,形成一个执行栈。
异步任务:
不进入主线程,而是进入任务队列,当主线程中的任务执行完毕,就从任务队列中取出任务放进主线程中来进行执行。由于主线程不断重复的获得任务、执行任务、再获取再执行,所以者种机制被叫做事件循环
执行顺序
- 先执行宏任务
- 宏任务执行完后看微任务队列是否有微任务
- 没有微任务执行下一个宏任务
- 有微任务将所有微任务执行
- 执行完微任务,执行下一个宏任务
运行结果:1,4,2,4