js-day4

深浅拷贝:

1.问题:赋值操作时,obja=objb会把b的地址赋值给a,这样使得修改a时候,b的内容也会改变。

2.浅拷贝:

    深浅拷贝都 针对的是引用类型,而浅拷贝拷贝的是地址。

   拷贝对象方法: object.assgin(新,旧) 和 展开运算符:{...旧}

   拷贝数组方法:array.prototype.concat() 和[...数组名]

    浅拷贝的问题: 普通对象类型直接拷贝值,如果原来的对象里面又嵌套一个对象,则嵌套的对象拷贝的又会是地址了,后面再修改会使得新旧都改变。

3.为了解决浅拷贝问题则用深拷贝:

  深拷贝的三种方式: 
   ①通过递归实现   

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

  例1:settimeout()到一定事件执行某个函数。 tolocalestring()获得当前的日期。实现计时器

               function getTime() {

                       document.querySelector('div').innerhtml = new Date().tolocalestring()

                       settimeout(getTime,1000)

                          }

           例子2:

                     

const obj = {

                       uname: 'pig',

                       age: 18,

                       hobby: ['足球', '篮球']

                      }

                  //新对象为空

                const o = { }

             //构造函数deepcopy把obj的内容赋值到o里面

                    function deepcopy(newobj, oldobj) {

           //k是属性名,oldobj[k]才是真正的值。

                  for (let k in oldobj) {  

             //对于拷贝来说,对象是简单对象直接赋值了。但是如果有数组,浅拷贝依然不能解决改变原来数组里面值的问题。要先判断oldobj[k],是否是数组类型

                 if(oldobj [k] instanceof Array){

                newobj[k] = [ ] //如果oldobj[k]是数组类型,则new[hobby]先设为空数组形式。再次进行对象里面小数组的deepcopy

                deepcopy(newobj[k], oldobj[k]) //相当于把old[hobby]赋值给new[hobby]

                 }else{  //如果不是数组类型直接赋值

                   newobj[k] = oldobj[k]

             }

          }

        }

  一定先判断对象,判断数组。再因为数组也是对象。

        //调用一下才执行

        deepcopy(o, obj)

        //console.log(o)

        o.hobby[0] = '羽毛球'

        console.log(obj)

        console.log(o)



  

     

  一定先判断对象,判断数组。再因为数组也是对象。

深拷贝:1.新的对象修改不会影响旧的值,且深拷贝需要用递归。

               2.普通拷贝直接赋值,若是数组和对象则再次利用递归,且是先判断Array再判断object。

       

  ②lodash/cloneDeep

           js库里面lodash的loaddeep方法,首先下载js库,再在script标签中单独进行引入

         一定是单独在一对<script></script>中引入!!!!错过两次了

<script src="./lodash.min.js"></script>
    <script>
        //引入js库,必须在script标签里面引用!!!

         const obj = {
                uname: 'pig',
                age: 18,
                hobby: ['足球', '篮球'],
                family: {
                    baby: 'pig1'
                }
            }
          const o = _.cloneDeep(obj)
           
           o.family.baby = 'pig2'

           console.log(obj)
           console.log(o)
        



    </script>

  ③通过JSON.stringify()实现

     简称 涮一下就是阳澄湖大闸蟹了。  转来转去两者的堆地址就不同了,所以两者之间修改是不互相影响的。

 //把对象转为json字符串用json.stringify, 再把字符串转为对象用parse.
     const obj2 = JSON.parse(JSON.stringify(obj1))



异常处理

1.throw异常.

      throw new Error('错误信息')   //类似一个错误函数

      throw抛出会终止程序。

2.try/catch捕获异常

try 是试一试下面代码是否会出错,catch是如果try代码出错则会报错,而且是需要传参数error的,这样才能打印出error.message,在catch里面加上return 才会终止程序,否则会继续执行下面操作。finally是无论代码是否出错都会执行的内容。

3.debugger

    用来调试时候立马会出现在debugger处。

处理this

1.普通函数this指向:

       谁调用就指向谁

         function fn() {

         conlose.log(this) //这个this就是指向window,因为是window.fn() fn是window的方法。

       }  

        const obj = {

         speak: function fn() { conlose.log(this)}//这里this指向obj。因为是obj.speak() .                                                                     

       }

            函数里面才有this,对象是没有this指向的

2.箭头函数

    箭头函数无this,this指向的是上一级的函数。

3.改变this 

   ①call()   很少用此方法. 传的参数是普通数

  ②apply()    传的是一个数组!!

         const  obj ={

              age: 18

                      }

          function fn(x, y) {

            console.log(this)  //this指向的是window

            console.log(x +y)

           }

     fn.apply(obj, [1, 2])   //this指向的是obj

 应用于:求数组的最大值!

    之前求数组里面最大值,先用运算符...展开数组变成数值,再用数学方法 Math.max(数值)。 

    现在求最大值,Math.max.apply(Math, arr)  //this指的是math,也可以写null谁也不指向。 这里重点在于我可以传数组到max去比较!!!

③bind()  不会调用函数。只会改变this。

                区别:前两个都是返回的是调用的函数结果。 而这个返回的是一摸一样的函数内容,只是this指向改变了而已。

三者的

       相同点:

            都可以改变函数内部的 this 指向.

        区别点:
             call 和 apply 会调用函数,并且改变函数内部 this 指向.
            call 和 apply 传递的参数不一样, call 传递参数aru1,aru2..形式 apply 必须数组形式[                     arg ]
           bind 不会调用函数,可以改变函数内部 this 指向.
        主要应用场景:
                call 调用函数并且可以传递参数
                apply 经常跟数组有关系.比如借助于数学对象实现数组最大值最小值
                bind 不调用函数,但是还想改变 this 指向.比如改变定时器内部的 this 指向.

防抖

   单位时间内,频繁触发事件,只执行最后一次。

  例子:划过盒子则盒子内数字+1,如果在盒子划一圈则会一直+1,防抖就是划一圈只会执行最后一次划过才+1.

处理方法:

     _.debounce(执行的函数, 等待时间)

手写防抖函数:

   核心利用settimeou定时器来实现的

  1. 声明定时器的变量

   2.每次鼠标移动的时候就要先判断是否有定时器,如果有定时器则先清除定时器。

 3.如果没有定时器,就开启定时器,存到定时器变量里面。

  4.定时器里面写函数调用

function debounce (fn,t) {
let timer
 return function () {
  
if (timer) clearTimeout(timer)
   timer = setTimeout(function () {
     fn()},t) 
}
}
box.addEventListener('mousemove', debounce(mousemove), 500)

 

   

  

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值