浅拷贝和深拷贝、继承

164 阅读3分钟

一、浅拷贝

浅拷贝和深拷贝都只针对于引用数据类型,浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存

二、深拷贝

不同于浅拷贝,深拷贝会另外创造一个一模一样的对象,修改新对象不会改到原对象

三、判断深、浅拷贝

1concat()方法
2slice()方法
3、Array.from()方法
4、拓展运算符

四、实现浅拷贝和深拷贝

1、Object.assign方法
2、_.clone(obj1) 使用lodash
3、{..obj}

4.1、数组的浅拷贝

虽然slice,concat能拷贝,只能拷贝数组的成员是值类型

4.2、深拷贝

 1JSON. stringify和JSON. parse能够实现深拷贝
但是它拷贝的对象中,有方法,会被丢失;
 2、使用第三方js库实现拷贝
 

4.3、手写拷贝

   function cloneDeep(params){
      let temp=Array.isArray(params)?[]:{};
      for(let key in params){
      if(typeof params[key]=="object"){
          temp[key]=cloneDeep(params[key])
      }else{
          temp[key]=params[key]
      }
      }
      return temp;
   }

五、检测数据类型

typeofinstanceof操作符都是用来判断数据类型的,但是它们的使用场景却各不相同。

区别

typeof与instanceof都是判断数据类型的方法,区别如下:

  • typeof会返回一个运算数的基本类型,instanceof 返回的是布尔值
  • instanceof可以准确判断引用数据类型,但是不能正确判断原始数据类型
  • typeof虽然可以判断原始数据类型(null 除外),但是无法判断引用数据类型(function 除外)

5.1封装检测数据类型的工具

    function checkType(obj){
        let temp=Object.prototype.toString.call(obj).split(" ");
        var str=temp[1];
        return str.slice(0,str.length-1);
    }

六、原型

原型:每个函数都自带一个属性(prototype),它的值是一个对象

作用:为构造函数添加公共共享的属性和方法,但是不建议把属性添加到原型上,每个对象都有自己的独特属性的值

原型链:每个'实例对象'都会自带一个属性(__ proto_ ) ,它就是对象的指针,它指向构造函数的原型.当通过实例对象访问个属性或方法时,会通过constructor访问构造函数的属性,如果构造函数内部不存在该属性和方法,就同通过_ proto__, 去访问原型对象,又如果原型对象不存在该属性和方法,又会继续通过__proto__ 往上一层的原型里进行查找,这个查找的过程就是原型链

七、继承

1. 对象冒充继承  使用 bind,call,apply
	缺点:不能继承原型上的属性和方法      
2. 原型链继承   缺点:不能让构造函数的属性,初始化
3. 组合继承 (对象冒充+原型继承)
    缺点:原型中会有多余的属性,并且是undefined
4. ES6classextends继承
5. 寄生组合继承  Object.create(base.prototype);

八、闭包

闭包:函数嵌套函数,内部函数可以引用外部函数的参数和变量,参数和变量不会被垃圾回收机制所收回. 

1、函数内部的变量不能超出范围,否则访问不了;
2、当函数执行完成后,函数内部的局部变量,会被销毁;

九、手写节流和防抖

防抖

     function debounce(callback,delay=600){
           var timer;
            return function(e){
                clearTimeout(timer);
                timer=setTimeout(()=>{
                    callback.call(this,e)
                
            },delay)
            }
        }

节流

    oBox.onmousemove=throttle(tempfn);//throttle是页面加载就执行 而其内部的return函数是由事件触发才会执行
     function throttle(callback,delay=2000){//页面只执行一次
           var oldTime=Date.now();//1
           return function(e){  // n 这行的函数,会被onmousemove疯狂执行n次
            var newTime=Date.now(); //最新的时间
                if(newTime-oldTime>=delay){//最开始的时间,如果大于600毫秒就执行1次
                    callback.call(this,e);
                    oldTime=newTime;    //重写计时,把当前最新的时间,当前开始时间
                }
           }
        }