• js继承


    1.原型链通过子代的原型去new 祖先的构造函数。去继承。

    优点:

    缺点:

    • 创建子类实例时,不能向父类的构造函数中传递参数
    • 父类中所有引用类型的属性会被所有子类实例共享,也就说一个子类实例修改了父类中的某个引用类型的属性时,其他子类实例也会受到影响

    例子: a.pototype=new b(); // a,b都是构造函数,a继承b

    下面看看修改原型链上面原始值与引用值的区别:

    // 原始值
    Professor.prototype.tSkill = "java"; function Professor() { } var professor = new Professor(); Teacher.prototype = professor; function Teacher() { this.mSkill = "js"; this.students = 500; this.objs = { a: 1, b: 2, }; } var teacher = new Teacher(); Student.prototype = teacher; function Student() { this.pSkill = "html" } var student = new Student(); student.students++;
    // 修改原始值,原型祖先不会更改,会在自己本身新增一个属性
    // student.students=student.students+1;
    // 右边student.students可以通过原型链在Teacher获取到;
    // 左边的这个,可以看成对象新增属性,没有这个属性,就得新增这个属性

    // 引用值
    列子:

    student.objs.a = 11;
    student.objs.c = 3;
    // 修改对象值,会直接修改原型链祖先的值,不建议这样操作;十分不规范 console.log(student);
    console.log(teacher);

    不是所有的对象都继承与Object.prototype

    Object.create(null);

    2.借用构造函数继承(经典继承)

    优点:

    • 在子类构造函数中可以向父类的构造函数中传递参数
    • 避免了父类中的引用类型属性在子类中共享的问题

    缺点:

    • 父类原型对象上的方法子类继承不到
    function Parent(age) {
      this.name = "parent";
      this.age = age;
      this.hobby = ["sing", "rap"];
    }
    Parent.prototype.sayHi = function() {
      console.log("Hi");
    };
    function Child(age) {
      Parent.call(this, age);
      this.type = "child";
    }
    let child1 = new Child(15);
    let child2 = new Child(15);
    
    child1.hobby.push("basketball");
    console.log(child1.name); // parent
    console.log(child1.age); // 15
    console.log(child1.type); // child
    console.log(child1.hobby); // [ 'sing', 'rap', 'basketball' ]
    console.log(child2.hobby); // [ 'sing', 'rap' ]
    child1.sayHi(); // 报错,child1.sayHi is not a function

    3.组合继承

    优点:

    • 在子类构造函数中可以向父类的构造函数中传递参数
    • 避免了父类中的引用类型属性在子类中共享的问题
    • 父类原型对象上的方法子类也可以继承到

    缺点:

    • 父类构造函数被调用了两次
    function Parent(age) {
      this.name = "parent";
      this.age = age;
      this.hobby = ["sing", "rap"];
    }
    Parent.prototype.sayHi = function() {
      console.log("Hi");
    };
    function Child(age) {
      Parent.call(this, age); // 第二次调用Parent
      this.type = "child";
    }
    
    Child.prototype = new Parent(); // 第一次调用Parent
    Child.prototype.constructor = Child;
    
    let child1 = new Child(15);
    let child2 = new Child(15);
    
    child1.hobby.push("basketball");
    console.log(child1.name); // parent
    console.log(child1.age); // 15
    console.log(child1.type); // child
    console.log(child1.hobby); // [ 'sing', 'rap', 'basketball' ]
    console.log(child2.hobby); // [ 'sing', 'rap' ]
    child1.sayHi(); // Hi

    4.组合式继承优化1

    优点:

    • 在子类构造函数中可以向父类的构造函数中传递参数
    • 避免了父类中的引用类型属性在子类中共享的问题
    • 父类原型对象上的方法子类也可以继承到
    • 父类构造函数也只调用了一次

    缺点:

    • 向子类原型上增加属性或方法时会影响到父类原型
    function Parent(age) {
      this.name = "parent";
      this.age = age;
      this.hobby = ["sing", "rap"];
    }
    Parent.prototype.sayHi = function() {
      console.log("Hi");
    };
    function Child(age) {
      Parent.call(this, age);
      this.type = "child";
    }
    
    Child.prototype = Parent.prototype;
    Child.prototype.constructor = Child;
    // 向子类原型上增加testProp属性,同时会被添加到父类原型上
    Child.prototype.testProp = 1;
    console.log(Parent.prototype); // 1
    
    let child1 = new Child(15);
    let child2 = new Child(15);
    
    child1.hobby.push("basketball");
    console.log(child1.name); // parent
    console.log(child1.age); // 15
    console.log(child1.type); // child
    console.log(child1.hobby); // [ 'sing', 'rap', 'basketball' ]
    console.log(child2.hobby); // [ 'sing', 'rap' ]
    child1.sayHi(); // Hi

    5.组合式继承优化2

    优点:

    • 实现继承最有效的方式!

    缺点:

    function Parent(age) {
      this.name = "parent";
      this.age = age;
      this.hobby = ["sing", "rap"];
    }
    Parent.prototype.sayHi = function() {
      console.log("Hi");
    };
    function Child(age) {
      Parent.call(this, age);
      this.type = "child";
    }
    
    Child.prototype = Object.create(Parent.prototype);
    Child.prototype.constructor = Child;
    
    let child1 = new Child(15);
    let child2 = new Child(15);
    
    child1.hobby.push("basketball");
    console.log(child1.name); // parent
    console.log(child1.age); // 15
    console.log(child1.type); // child
    console.log(child1.hobby); // [ 'sing', 'rap', 'basketball' ]
    console.log(child2.hobby); // [ 'sing', 'rap' ]
    child1.sayHi(); // Hi
  • 相关阅读:
    acm入门 杭电1001题 有关溢出的考虑
    面向对象课后深入学习(C++ 类的静态成员详细讲解)
    Eclipse中导入项目后js报错解决方法
    mysql用户链接数
    配置服务器nginx 教程
    eclipse如何新建项目发布到git
    获取当天开始时间结束时间
    pdf在线加载·
    springmvc配置详解 教程
    hibulder中使用git教程
  • 原文地址:https://www.cnblogs.com/ssszjh/p/14377890.html
Copyright © 2020-2023  润新知