zoukankan      html  css  js  c++  java
  • js继承的几种方式

    js想要继承,先创建一个父类。

    function Person(name,age){
         this.name = name;  ----属性
         this.age = age;      
         this.sayThing = function(){  ---实例方法
        console.log('say something');
       } }

    1、原型链继承

    原型链是一种关系,实例对象和原型对象之间的关系,关系是通过原型(__proto__)来联系的。

    实例对象中有__proto__,是对象,叫原型,不是标准的属性,浏览器使用,并且有的游览器不支持。
    构造函数中有prototype属性,也是对象,叫原型。

    注意 原型中的方法是可以互相访问的。

    原型的简单语法:

    1、利用原型共享数据

    Person.prototype.height = '180cm';
    Person.prototype.eat=function(){
       console.log('吃早餐');  
      this.play(); }

    Person.prototype.play = function(){
      console.log('打球');
    }

    var person1 = new Person('张三',20);

    2、写法二:直接这么赋值,会导致constructor构造器属性消失,需要手动修改构造器指向。

    function Student(name,age,sex){
       this.name=name;
       this.age=age;
       this.sex=sex;
    }
    Student.prototype={
       constructor:Student, height:
    "188", weight:"55kg", study:function(){ console.log("好好学习i") } } var stu=new Student("小红",20,"男") console.dir(stu)

    构造函数和实例对象和原型对象之间的关系

    1、构造函数可以实例化对象
    2、构造函数中有一个属性叫prototype,是构造函数的原型对象
    3、构造函数的原型对象(prototype)中有一个constructor 构造器,这个构造器指向的就是自己所在的原型对象所在的构造函数
    4、实例对象的原型对象(__proto__) 指向的是该构造函数的原型对象(prototype)
    5、构造函数的原型对象(prototype)中的方法是可以被实例对象直接访问 

    更改原型链指向:

      function Person(age) {
        this.age = age;
      }
      Person.prototype.eat = function () {
        console.log('吃萝卜');
      }
    
      function Student(name) {
        this.name = name;
      }
      Student.prototype.play = function () {
        console.log('打篮球');
      }
    
      Student.prototype = new Person(19);
      var stu = new Student('张三');
    console.log('stu.age=', stu.age); --- 19 console.log('stu.name=', stu.name);  ----- 张三 console.log(stu.eat);  ----- function(){} console.log(stu.play); ----- undefined

    原型链是可以更改指向的,定义的构造函数 Student, 更改原型链指向Person,则指向了Person的构造函数。Person的 eat 方法可以得到,此时的 play 方法 因为指向改变了,所以找不到为undefined。但是构造函数Person 和 Student 里面的独立属性是都继承的。

    3、构造函数继承

    // 定义一个动物类
    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){ Animal.call(this);
     Person.call(this); ------- 可以引用多个父类构造函数
    this.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

    特点:

    1. 子类实例共享父类引用属性。
    2. 创建子类实例时,可以向父类传递参数
    3. 可以实现多继承(call多个父类对象)

    缺点:

    1. 实例并不是父类的实例,只是子类的实例
    2. 只能继承父类的实例属性和方法,不能继承原型属性/方法
    3. 无法实现函数复用,每个子类都有父类实例函数的副本,影响性能

    4、组合继承(组合原型链继承和借用构造函数继承)

      function Person(name) {
        this.name = name;
        this.sum = function () {
          return 'hello';
        }
      }
    
      function SubType(name) {
        Person.call(this, name)
      }
    SubType.prototype = new Person(); var sub = new SubType('李四'); console.log('sub.name=', sub.name); --- 李四 console.log('sub.sum =', sub.sum()); ---- hello

    重点:结合了两种模式的优点,传参和复用
    特点:1、可以继承父类原型上的属性,可以传参,可复用。
       2、每个新实例引入的构造函数属性是私有的。
    缺点:调用了两次父类构造函数Person()(耗内存),子类的构造函数会代替原型上的那个父类构造函数。

      

  • 相关阅读:
    剑指Offer-30.连续子数组的最大和(C++/Java)
    剑指Offer-29.最小的K个数(C++/Java)
    UVA 1616 Caravan Robbers 商队抢劫者(二分)
    UVA 10570 Meeting with Aliens 外星人聚会
    UVA 11093 Just Finish it up 环形跑道 (贪心)
    UVA 12673 Erratic Expansion 奇怪的气球膨胀 (递推)
    UVA 10954 Add All 全部相加 (Huffman编码)
    UVA 714 Copying Books 抄书 (二分)
    UVALive 3523 Knights of the Round Table 圆桌骑士 (无向图点双连通分量)
    codeforecs Gym 100286B Blind Walk
  • 原文地址:https://www.cnblogs.com/liumcb/p/13632043.html
Copyright © 2011-2022 走看看