zoukankan      html  css  js  c++  java
  • JS----this && JS继承

    参考学习:https://www.cnblogs.com/lisha-better/p/5684844.html
    1.普通函数调用(window)
    2.作为构造函数调用()
    3.作为方法调用
    4.使用call/apply/bind调用
    5.ES6箭头函数调用(this取决于包裹箭头函数的第一个普通函数)

    **setTimeout()由window对象调用
    call()参数为空,this指向window
    匿名函数,this也指向window
    在这里插入图片描述

    在事件中,this指向触发这个事件的对象,特殊的是,IE中的attachEvent中的this总是指向全局对象Window

    参考学习:https://www.cnblogs.com/chenwenhao/p/6980401.html
    https://www.imooc.com/article/20162
    https://www.cnblogs.com/humin/p/4556820.html

    在这里插入图片描述关于Function和Object创建实例之间的关系
    在这里插入图片描述基于原型链继承的链图,对继承有个具体化的概念: (这个是核心继承部分)
    上图整体的继承链

    js继承:
    1.原型链继承
    特点;

       1.要想为子类新增属性和方法,必须要在new Animal()这样的语句之后执行,不能放到构造器中
        2.无法实现多继承
        3.来自原型对象的所有属性被所有实例共享
        4.创建子类实例时,无法向父类构造函数传参
    
    
      function SuperType () {
        this.property = true;
    }
    
    SuperType.prototype.getSuperValue = function() {
        return this.property;
    };
    
    function SubType() {
        this.subproperty = false;
    }
    
    //继承SuperType
    **SubType.prototype = new SuperType();**
    
    SubType.prototype.getSubValue = function() {
        return this.subproperty;
    }
    
    var instance =new SubType();
    console.log(instance.getSuperValue());  // true
    

    存在问题:

    1.包含引用类型值的原型属性会被所有实例共享(修改),而在构造函数中的基本类型和引用类型属性均不可改变(const附体)
    2.创建子类型的实例时,不能向超类的构造函数中传递传递参数
    3.无法实现多继承

    2.构造函数继承(在子类型构造函数的内部调用超类型)

    子类型构造函数中向超类型构造函数传参
    

    问题:函数无法复用

     function SuperType() {
         this.colors = ["red","blue","green"];    
    }
    
    function SubType() {
       //继承了SuperType   --重新创建SuperType构造函数属性的副本
       SuperType.call(this);
    }
    
    var instance1 = newe SubType();
    instance1.colors.push("black");
    console.log(instance1.colors);  //"red,blue,green,black"
    
    var instances2 = new SubType();
    console.log(instance2.colors);  //"red,blue,green" --完美实现了继承构造函数属性
    

    3.组合继承(避免了原型链和构造函数继承的缺陷)

    弥补了方式2的缺陷,可以继承实例属性/方法,也可以继承原型属性/方法
    既是子类的实例,也是父类的实例
    不存在引用属性共享问题
    可传参
    函数可复用

    缺点:

    调用了两次父类构造函数,生成了两份实例(子类实例将子类原型上的那份屏蔽了)

    function SuperType(name) {
        this.name = name;
        this.colors = ["red","blue","green"];
    }
    
    SuperType.prototype.sayName = function() {
        console.log(this.name);
    };
    
    function SubType(name,age){
        //继承属性  --重新创建SuperType构造函数属性的副本
        SuperType.call(this,name);
    
        this.age = age;
    }
    
    //继承方法
    SubType.prototype = new SuperType();
    SubType.prototype.constructor = SubType;
    SubType.prototype.sayAge = function() {
        console.log(this.age);
    };
    
    var instance1 =new SubType("Nicholas",29);
    instance1.colors.push("black");
    console.log(instance1.colors);   // "red,blue,green,black"
    instance1.sayName();       // "Nicholas"
    instance1.sayAge();       // 29
    
    var instance2 = new SubType("Greg",22);
    console.log(instance2.colors);  // "red,blue,green"
    instance2.sayName();    // "Greg"
    instance2.sayAge();    // 22
    

    4.实例继承
    特点:

    不限制调用方式,不管是new 子类()还是子类(),返回的对象具有相同的效果

    缺点:

    实例是父类的实例,不是子类的实例
    不支持多继承

    // 定义一个动物类
    function Animal (name) {
      // 属性
      this.name = name || 'Animal';
      // 实例方法
      this.sleep = function(){
        console.log(this.name + '正在睡觉!');
      }
    }
    // 原型方法
    Animal.prototype.eat = function(food) {
      console.log(this.name + '正在吃:' + food);
    };
    function Cat(name){
      var instance = new Animal();
      instance.name = name || 'Tom';
      return instance;
    }
    
    // Test Code
    var cat = new Cat();
    console.log(cat.name);
    console.log(cat.sleep());
    console.log(cat instanceof Animal); // true
    console.log(cat instanceof Cat); // false
    

    5.拷贝继承
    特点:

    支持多继承

    缺点:

    效率较低,内存占用高(因为要拷贝父类的属性)
    无法获取父类不可枚举的方法(不可枚举方法,不能使用for in 访问到)

    function Cat(name){
      var animal = new Animal();
      for(var p in animal){
        Cat.prototype[p] = animal[p];
      }
      Cat.prototype.name = name || 'Tom';
    }
    
    // Test Code
    var cat = new Cat();
    console.log(cat.name);
    console.log(cat.sleep());
    console.log(cat instanceof Animal); // false
    console.log(cat instanceof Cat); // true
    

    6.寄生组合继承

    function Cat(name){
      Animal.call(this);
      this.name = name || 'Tom';
    }
    (function(){
      // 创建一个没有实例方法的类
      var Super = function(){};
      Super.prototype = Animal.prototype;
      //将实例作为子类的原型
      Cat.prototype = new Super();
    })();
    
    // Test Code
    var cat = new Cat();
    console.log(cat.name);
    console.log(cat.sleep());
    console.log(cat instanceof Animal); // true
    console.log(cat instanceof Cat); //true
    
  • 相关阅读:
    [php]php时间戳当中关于时区的问题
    [jQuery] jQuery如何获取同一个类标签的所有的值
    sed 命令基础
    Docker 学习第6课
    Docker 学习第五课
    Docker 学习第四课
    Docker 学习第三课
    Docker 学习第二课
    Docker学习第一课
    XdeBug的使用
  • 原文地址:https://www.cnblogs.com/princeness/p/11664967.html
Copyright © 2011-2022 走看看