JS高级03

一、浅拷贝

拷贝:浅拷贝和深拷贝:只针对引用数据类型

浅拷贝:拷贝的是地址

常见方法:

1.拷贝对象:

Object.assign(新的空的对象,老的有值的对象):Object.assign(o,obj)

展开运算符:var o = {...obj}

2.拷贝数组:

展开运算符:var arr1=[...arr]

var arr1=[].concat(arr)

    <script>
       var obj={
        name:'王多磊',
        age:['18','28','38'],
        sex:'不祥'
       }

    //    var obj1=obj
       
    //    引用数据类型复制给其他变量时,只是指向堆的url地址复制了一份,只要值改变,其他的变量里面的值也会跟着改变
    //    console.log(obj)
    //    console.log(obj1)
    //    拷贝  浅拷贝   1 Object.assign浅拷贝 只能拷贝第一层的基本数据类型    2 扩展运算符 浅拷贝  

    // var o={}
    // Object.assign(o,obj)
    // obj.name='麻子'
    // obj.age[0]='40'
    // obj.sex='男'
    // console.log(o)

    //  var o={...obj}
    //  obj.name='郑日安'
    //  console.log(o)

// 数组浅拷贝  1 concat实现浅拷贝    2 扩展运算符实现浅拷贝
var arr=['12','王多磊',{name:'小磊磊'}]

// concat

// var arr1=[].concat(arr)
// arr.name='老王'
// arr.age='28'
// arr[2].name='小邓'
// console.log(arr1)//12 王多磊 小邓

var arr1=[...arr]
arr[1]='老王'
arr[0]='28'
arr[2].name='小邓'
console.log(arr1)//12 王多磊 小邓
console.log(arr)//28 老王 小邓
    </script>

二、函数递归

函数递归:函数内部自己调用自己

作用:类似循环

注意:栈溢出 加return

递归案例:输入id号可以返回对应的数据对象

    <script>
        // 输入id号可以返回对应的数据对象
        var arr = [{
            id: 1,
            uname: '电脑',
            groups: [
                {
                    id: 2,
                    uname: '键盘',
                    groups: [
                        {
                            id: 3,
                            uname: '鼠标'
                        },
                        {
                            id: 4,
                            uname: '散热器'
                        },
                    ]
                }, 
                {
                    id: 5,
                    uname: '电脑包'
                }
            ]
        },
        {
            id: 6,
            uname: '电脑支架'
        }
        ];

        // var arr1=[{},{}]
     function getID(arrs,id){
        var obj={}
        arrs.forEach(function(item){
            // console.log(item)  // item拿到的是arr数组的外层两个元素(id是1的时候)
            if(item.id==id){
                obj=item
            }
            else if(item.groups&&item.groups.length>0){
                // 想要里层数据可以使用递归函数拿到,数据里面应该有groups并且长度需要大于0
                obj =  getID(item.groups,id)
            }
            //  只要有groups这个属性,就还有一层嵌套
        });
        return obj
     }

//  console.log(getID(arr,1))  
//  console.log(getID(arr,2))  
 console.log(getID(arr,4))  
//  var tree =getID(arr,4)
    </script>

三、深拷贝

深拷贝:拷贝的是对象,不是地址

常见方法:

1.通过递归实现深拷贝

2.lodash/cloneDeep

3.通过JSON.stringify()实现

深拷贝实现:

1.深拷贝出来的新对象不会影响老对象,用到函数递归

2.普通拷贝直接赋值,遇到数组再次调用递归函数

3.遇到对象再次调用递归函数解决

先Array,再对象

        var obj = {
            uname:'pink',
            age:18,
            habby:['乒乓球','足球'],
            family:{
                baby:'小pink'
            }
        }
        var o = { }
        //拷贝函数
        function deepCopy(newObj,oldObj){
            for(var k in oldObj){
                //处理数组问题 一定先写数组 再写对象 不能颠倒
                if(oldObj[k] instanceof Array){
                    newObj[k] = []
                    //newObj[k]接收[] habby
                    //oldObj[k] ['乒乓球','足球']
                    deepCopy(newObj[k],oldObj[k])
                }
                else if(oldObj[k] instanceof Object){
                    newObj[k] = {}
                    //newObj[k]接收[] habby
                    //oldObj[k] ['乒乓球','足球']
                    deepCopy(newObj[k],oldObj[k])
                }
                
                else {
                //k 属性名 uname oldObj[k] 属性值 18
                // newObj[k]//newObj[k]===o.k
                // newObj[k] === o.uname
                newObj[k] = oldObj[k]//把老的值赋给新的属性
                }                
            }
        }
        deepCopy(o,obj)//函数调用 两个参数 o 新对象 obj 旧对象
        console.log(o);//{uname: 'pink', age: 18}
        o.age=20
        o.habby[0]='篮球'
        o.family.baby = '老pink'
        console.log(obj);//{uname: 'pink', age: 18}
    <script>
        // 想把整个obj全部拷贝出来,可以使用递归进行拷贝
        var obj = {
            id: 1,
            name: '李四',
            color: ['blue', 'red'],
            msg: {
                age: 20
            }
        }
        function cloneDeep(copyObj) {
            // 创建一个变量,因为不确定数据类型,所有先不赋值          
            var obj
            if(Array.isArray(copyObj)){
                // 如果copyObj是数据,那就给obj赋值为空数组
                obj=[]
                // 通过数组的遍历进行拷贝
                // 由于数组的元素可以是任意值,所以需要对内部进行判断数据类型
                // obj[i]=cloneDeep(copyObj[i])通过这个方法进行回调,完成数据类型的判断
                for(var i=0;i<copyObj.length;i++){
                    obj[i]=cloneDeep(copyObj[i])
                }
                // 通过回电函数完成拷贝,返回obj
                return obj
            }else if (copyObj instanceof Object){
                // 给obj一个空对象
                obj={}
                for(var k in copyObj){
                    obj[k]=cloneDeep(copyObj[k])
                }
                return obj
            }else{
                return copyObj
            }
           
        }
     var  newObj=cloneDeep(obj)
     obj.msg.age=50
     console.log(obj)
     console.log(newObj)
    </script>
    <script>
        // 想把整个obj全部拷贝出来,可以使用递归进行拷贝
        var obj = {
            id: 1,
            name: '李四',
            color: ['blue', 'red'],
            msg: {
                age: 20
            }
        }
       var newObj=_.cloneDeep(obj)
       obj.msg.age=50
       console.log(obj)
       console.log(newObj)
    </script>

四、防抖

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="lodash.min.js"></script>
    <style>
        div{
            width: 200px;
            height: 200px;
            background-color:skyblue;
            margin:  0 auto;
            line-height: 200px;
            text-align: center;
            font-size: 24px;
        }
    </style>
</head>
<body>
    <div>1</div>
    
    <script>
        console.log(_)
        // 防抖:在单位时间内,频繁触发事件,只执行最后一次,  (例如:1秒内,只要有新的触发事件产生,就从0开始计时)
        // 用户输入input、手机号验证、密码验证、邮箱验证
          
    // 鼠标移动就自加一
    var div=document.querySelector('div')
    var num=1

    function fn(){
        div.innerHTML=num++
    }
    // fun 要放抖动的函数
    // wait  是延迟的时间
    div.addEventListener('mousemove', _.debounce(fn,1000))
    </script>
</body>
</html>

五、手写防抖

<body>
    请输入内容:<input type="text">
    
    <script>
        // 声明一个定时器变量用于存储定时器
        // 当输入内容时(当事件触发时),都先判断一下有没有定时器,有的话就先清除之前的定时器
        // 没有定时器的话,就向下执行,把定时器赋值给timer
        // 开始执行定时器里的内容
       var input=document.querySelector('input')
       var timer
       input.addEventListener('input',function(){
         if(timer) clearTimeout(timer)
        timer= setTimeout(function(){
            console.log(input.value)

        },3000)
       })
    </script>
</body>

六、节流

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="lodash.min.js"></script>
    <style>
        div{
            width: 200px;
            height: 200px;
            background-color: skyblue;
            margin: 0 auto;
        }
    </style>
</head>
<body>
    <div></div>
    <script>
    /* 
        防抖节流的区别:防抖是只要在规定时间内重复触发不停止的情况下,就不会执行代码
        节流是只要你在重复触发不停止的情况下,在规定时间执行完后就会执行下一次
    */
        // 节流:在规定时间内,频繁触发事件,只执行一次
        // 例如:1秒内,只要有新的触发事件产生,无效,除非之前的触发事件执行完毕
        // 场景:scroll  页面尺寸缩小

        var div=document.querySelector('div')
        var num=1
        function fn(){
        div.innerHTML=num++
    }
        div.addEventListener('mousemove',_.throttle(fn,1000))
    </script>
</body>
</html>

七、手写节流

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
         .box {
            height: 3000px;
        }
    </style>
</head>
<body>
    <div class="box"></div>

    <script>
        var timer;
        document.addEventListener('scroll',function(){
        console.log(window.pageYOffset)
        if(window.pageYOffset>200){
            if(!timer){
                timer = setTimeout(function(){
                console.log('我被卷上去了')
                timer=null             
            // 在setTimeout定时器里面无法清除定时器,因为定时器还在执行,所以需要用timer=null手动置空定时器
            // clearTimeout(timer)
            },3000)
            }            
        }
     })
    </script>
</body>
</html>

八、清除定时器

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
         .box {
            height: 3000px;
        }
    </style>
</head>
<body>
    <div class="box"></div>
    
    <script>   
    var timer;   
    timer=setTimeout(function(){
        // clearTimeout(timer)
        timer=null
        console.log(timer)
    },1000)
    </script>
</body>
</html>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值