“这是我参与8月更文挑战的第N天,活动详情查看:8月更文挑战”
写在前面: 这其实就相当于是之前那篇JavaScript高级的补充(修改)(增加),也有一些是前段时间面试碰到的面试题目,记录下来,与君共勉.
事关我对于JS高级的补充
浅拷贝和深拷贝
简单类型数据是直接存储在栈里面的,通过赋值操作可以直接复制一个值出来,但复杂类型数据是存储在堆里面的,栈里面只是保存了其在堆中的地址值(指针),所以才会有浅拷贝和深拷贝的概念.
浅拷贝概念
对象通过赋值或操作能把第一级属性和方法拷贝下来,但如果该对象有子对象的话,子对象是不会拷贝成功的,还是引用子对象的地址值,依旧会收到干扰,这叫浅拷贝
//浅拷贝的方法有
let arr1 = {name:"Ace"};
let arr2 = {name:"Bob"};
arr1 = arr2; //直接赋值
arr1 = Object.assign(arr2); //Object.assign()函数
let arr3 = [...arr1,...arr2] //扩展字符串
复制代码
深拷贝概念
通过递归遍历的方式深度赋值每一个对象及其子对象,直到再无子对象为止,或者把整个对象先变成简单类型的字符串数据,赋值之后再转回复杂类型的对象数据.
//深拷贝的方法主要有两种
let arr1 = {name:"Ace"};
let arr2 = {name:"Bob"};
arr1 = Json.parse(Json.stringify(arr2)); //数据类型转换再拷贝
arr1 = deepClone(arr2) //递归遍历引用类型数据拷贝
//Json方式的缺点:拷贝不了Date数据,正则对象,Error对象,undefined等等
//深拷贝函数
function deepClone (obj={}){
//1.判断传入的数据是否为对象格式
if(typeof obj !== 'object' || obj == null{
return obj;
}
let result = null;
//2.判断数据是对象还是数据
obj instanceof Array ? result = [] : result = {};
//3.遍历对象的key值,并且函数递归调用.
for(let key in obj){
if(obj.hasOwnProperty(key){
result[key] = deepClone(obj[key]);
}
}
}
复制代码
事件冒泡,委托,监听,代理
事件冒泡
子元素的事件向上冒泡给父元素直到根元素
阻止事件冒泡stopPropagation()
事件捕获
从根元素一直向下捕获到子元素
阻止默认事件preventDefault()
事件委托(事件代理)
通过给父元素事件委托注册到异步加载的子元素
事件监听
获取某个元素的Nodelist,通过遍历给每一个子元素都添加事件监听.
取两个数组的交集,并集和差集
取数组并集
//把两个数组合并成一个数组再用Set结构的特性去重
const Values = [...new Set([...arr1,...arr2])];
console.log(Values.join(''))
复制代码
取数组交集
//把arr1里面的每一项都传入arr2里面进行includes校验,如果存在返回true否则false来判断当前item是否相交,再取出相交的数据进行去重
const Values = [...new Set(arr1)].filter(item => {
if(arr2.includes(item)){
return item;
}
})
//
const Values = [...new Set(arr1.filter(items => arr2.some(ele => ele === items)))]
console.log(Values.join(''))
复制代码
取数组差集
//
const Values = arr1.filter(items => !arr2.some(ele => ele === items))
console.log(Values.join(''))
复制代码
防抖和节流
防抖
当持续触发事件时,在一定时间内没有再次触发该事件,事件处理函数才会执行一次
function debounce(fn,delay){
let timer = null //借助闭包
return function() {
if(timer){
clearTimeout(timer) //进入该分支语句,说明当前正在一个计时过程中,并且又触发了相同事件。所以要取消当前的计时,重新开始计时
timer = setTimeout(fn,delay)
}else{
timer = setTimeout(fn,delay) // 进入该分支说明当前并没有在计时,那么就开始一个计时
}
}
}
复制代码
节流
当持续触发事件时,一定时间内无论触发多少次,实际都只会执行一次
function throttle(fn,delay){
let valid = true
return function() {
if(!valid){
//休息时间 暂不接客
return false
}
// 工作时间,执行函数并且在间隔期内把状态位设为无效
valid = false
setTimeout(() => {
fn()
valid = true;
}, delay)
}
}
复制代码
JS的垃圾回收机制
内存泄漏
定义了的变量或对象却从来未曾使用,或者使用了之后就不再需要但却没有删除的情况,就是会造成内存泄漏
如何防止内存泄漏
-
少不必要的全局变量,或者生命周期较长的对象,及时对无用的数据进行垃圾回收
-
注意程序逻辑,避免“死循环”之类的 ;
-
避免创建过多的对象 原则:不用了的东西要及时归还
-
使用定时函数定时去清理
垃圾回收机制是什么
就是不停的寻找代码中不会被使用的变量和数据,并将其删除,防止浏览器内存泄漏的一种浏览器机制,最常见的垃圾回收方式是标记清除
工作原理
是当变量进入环境时,将这个变量标记为“进入环境”。当变量离开环境时,则将 其标记为“离开环境”。标记“离开环境”的就回收内存,当有些变量持有标记却一直未被调用和引用的时候,垃圾回收器就会将其删除.
End