事关我对于JS高级的更多理解

“这是我参与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

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享