day31-继承与闭包

01.原型对象

在这里插入图片描述

  • 原型链:当前对象到Object的原型对象之间的链条

    • 原型:原型对象(prototype__proto__
    • 属性访问规则
      1. 从当前对象中查找,找不到则返回,否则进入第2步
      2. 在原型对象中查找,找到则返回,否则进入第3步
      3. 在原型对象的原型查找,找到则返回,否则继续往原型中查找,依此类推
      4. 直到 Object 的原型对象中查找(终点),找到则返回,否则(属性:得到的是undefined,方法:xxx is not a function)
  • 内置原型对象

let username="jingjing";
username.toUpperCase();
username.length; //8
  • 内置原型对象 类型
    • Number
    • String
    • Boolean
    • Array
    • Function
    • Date
    • RegExp
    • … …
  • 扩展内置原型对象

    原则:判断不存在时才添加

  • 重置原型对象:一次性扩展多个方法

    避免覆盖原始属性/方法

            if(!Date.prototype.formatDate){
                Date.prototype.formatDate = function(){}
            }
            if(!Date.prototype.fromNow){
                Date.prototype.fromNow = function(){}
            } 
            //  ...
            //  重置原型对象
            function Date(){}
            Date.prototype={
                formatDate(){},
                fromNow(){},
                // ...
                ...Date.prototype,
           }
           Object.defineProperty(Date.prototype,"constructor",{
                configurable:true,
                value:Date
           })
          
           

02.重置原型对象

        Date.prototype = {
            formatDate() { },
            fromNow() { },
            //...
            ...Date.prototype,
        }
       // Object.assign(target,obj1,obj2,...,objN), jQuery.extends()
        Object.assign(Date.prototype, {
            formatDate() { },
            fromNow() { },
        });
        // Object.assign()的使用
        let jj = { username: 'jingjing', password: 123, age: 36,score:{en:85,math:70,cn:86} };
        let obj1 = { gender: '女', age: 37 }
        Object.assign(jj, obj1, { gender: '不详', money: 1000000, username: 'jingjing plus' });

        console.log('jj=', jj);

        // 利用Object.assign()实现拷贝:(浅拷贝)
        let jjmm = Object.assign({},jj);

        // 浅拷贝
        let jjjj = {...jj};

        // 深拷贝
        // * 递归复制
        // * JSON.stringify()/JSON.parse()
        let jjBrother = JSON.parse(JSON.stringify(jj));
        console.log('jjBrother',jjBrother);
深拷贝

在这里插入图片描述

浅拷贝

在这里插入图片描述

03.继承

继承概念

  • 继承是面向对象中一个非常重要的特性
  • 指的是子类继承父类的属性和方法

继承的好处

  1. 子类拥有父类所有的属性和方法(代码复用)
  2. 子类可以扩展自己的属性和方法(更灵活)
  3. 子类可以重写父类的方法

继承的方式

  • 01.原型链继承法
    • 核心:用父类(User)实例来充当子类(Son)原型对象
    • 缺点:
      • 无法继承构造函数的属性
      • 创建子类实例时,无法向父类构造函数传参
      • 原型对象中存在多余的属性
Son.prototype=new User;
  • 02.借用构造函数法

    • 核心:借父类的构造函数来增强子类实例,相当于把父类的实例属性复制一份给子类实例
      • call:父类.call(子类实例,参数1,参数2...)
      • apply:父类.apply(子类实例,[参数1,参数2...])
      • 区别:传参不同,call为多个参数,apply只能由两个参数,第二个参数为数组
  • 03.组合继承(最常用的继承方式)

    • 继承属性:借用构造函数法

      • 只在构造函数中定义属性
    • 集成方法:原型链继承法

      • 把所有的方法写入原型对象
    • 缺点(原型链继承法的缺点):

      • 在原型对象中生产多余的属性
      • 多次执行父类构造函数
  • 04.原型式继承:

    • 核心:先创建一个临时的构造函数,然后将传入的对象作为这个构造函数的原型,最后返回这个临时构造函数的一个新实例
      • 解决了原型链继承的缺点:生成多余的属性
function object(o){
   function F(){}
   F.prototype=0;
   return new F();
}
  • ES5版本的原型式继承:Object.creat()
Son.prototype = Object.create(User.prototype)

04.ES6类继承

<script>
  /**ES6类继承
      *类:clsaa
      *继承:extends
  **/
  class Popover{
     //静态方法
     //注意:ES6只支持静态方法,不支持静态属性
     static show(){
         console.log("hello show")
     }
     constructor(){
         //在这里定义属性(写在实例上)
         this.type="popover"
     }
     
     //在这里定义方法(写在原型上)
     init(){}
     drag(){}
     open(){}
     colse(){}
  }
  const pop1=new Popover();
  console.log("pop1=",pop1)

  //继承
  class Confirm extends Popover{
      //如果继承父类,并且实现自己的constructor,则必须在constructor中调用super(),只有调用super后才能使用this
      constructor(){
          super();
          this.type="confirm"
      }
      init(){}
  }
  const conf1=new Confirm();
  console.log("conf1",conf1)
</script>

在这里插入图片描述

05.闭包

  • 概念:闭包是指 有权访问另一函数作用域中的变量的函数
  • 变量访问规则:使用就近原则在作用域链查找,只能往外找,不能往里找。
  • 好处:
    • 可在外部操作函数内部的变量
    • 让变量长期驻留内存以便下次使用
  • 注意:由于闭包会携带包含它的作用域(运行环境),因此会比其他函数占用内存,过度使用闭包可能会造成性能问题
let num=10;
function test(){
  let n=20;
  console.log(n);
}
// test(); //20
// test(); //20
// test(); //20

function show(){
  var n=20;
  //定义一个函数add
  function add(){
     n++;
     console.log(n);
  }
  //返回add函数,这时,在js中就形成了一个闭包,add成为闭包函数
  return add;
}
// show()() //21
// show()() //21
// show()() //21
const res =show();
res(); //21
res(); //22
res(); //23

//垃圾回收机制(自动:判断变量是否还有用,自动清除没用的变量)
// *引用计数法:判断变量是否被其他引用
// *标记清除法:给变量添加标记

06.利用闭包获取点击按钮的索引值

在这里插入图片描述

<script>
   let btns=document.querySelectorAll("button");
   for(let i=0;i<btns.length;i++){
      btns[i].onclick=(function(i){
         function handleClick(){
            console.log('i=',i)
         }
         return handleClick;
      })(i);
   }
</script>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值