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()(耗内存),子类的构造函数会代替原型上的那个父类构造函数。

      

  • 相关阅读:
    cogs 2507 零食店
    动态规划练习们~
    codevs 访问艺术馆
    搜索练习 (主要练剪枝23333)
    codevs 3119 高精度练习之大整数开根 (各种高精+压位)
    EntityFramework 两个参数连续(中间有空格)问题
    Mysql DELETE 不能使用别名? 是我不会用!
    MySQL 空间数据 简单操作
    C# String 字符拼接测试(“+”、string.Format、StringBuilder 比较)
    EntityFramework 事物引发的问题
  • 原文地址:https://www.cnblogs.com/liumcb/p/13632043.html
Copyright © 2011-2022 走看看