js的继承

JavaScript是一种基于原型的编程语言,这意味着每个JavaScript对象都有一个原型对象,对象可以从其原型继承属性和方法。在JavaScript中,有几种实现继承的方法,以下是一些常见的继承方式:

  1. 原型链继承
    原型链继承是最基本的继承方式。通过将一个对象的原型指向另一个对象,实现属性和方法的继承。

    function Parent() {
      this.name = 'Parent';
    }
    Parent.prototype.sayHello = function() {
      console.log('Hello from ' + this.name);
    };
    
    function Child() {
      // 继承属性
      this.age = 10;
    }
    // 设置Child的原型为Parent的一个实例
    Child.prototype = new Parent();
    
    var child = new Child();
    child.sayHello(); // 输出: Hello from Parent
    
  2. 借用构造函数继承(也称为经典继承):
    通过在子类的构造函数中调用父类的构造函数,实现属性的继承。

    function Parent(name) {
      this.name = name;
    }
    
    function Child(name, age) {
      // 借用Parent的构造函数
      Parent.call(this, name);
      this.age = age;
    }
    
    var child = new Child('Alice', 5);
    console.log(child.name); // 输出: Alice
    
  3. 组合继承
    组合继承结合了原型链继承和借用构造函数继承的优点,解决了借用构造函数继承时无法访问父类原型方法的问题。

    function Parent(name) {
      this.name = name;
    }
    Parent.prototype.sayHello = function() {
      console.log('Hello from ' + this.name);
    };
    
    function Child(name, age) {
      Parent.call(this, name); // 借用构造函数
      this.age = age;
    }
    
    // 设置Child的原型指向Parent的原型
    Child.prototype = Object.create(Parent.prototype);
    Child.prototype.constructor = Child;
    
    var child = new Child('Alice', 5);
    child.sayHello(); // 输出: Hello from Alice
    
  4. 原型式继承
    使用一个函数动态创建一个对象,该对象的原型是传入的对象。

    function object(o) {
      function F() {}
      F.prototype = o;
      return new F();
    }
    
    var Parent = { name: 'Parent' };
    var Child = object(Parent);
    Child.name = 'Child';
    console.log(Child.name); // 输出: Child
    
  5. 寄生式继承
    创建一个仅用于封装继承过程的函数,通过修改原型对象来实现继承。

    function inherit(o) {
      var F = function() {};
      F.prototype = o;
      return new F();
    }
    
    var Parent = { name: 'Parent' };
    var Child = inherit(Parent);
    Child.name = 'Child';
    console.log(Child.name); // 输出: Child
    
  6. 寄生组合式继承
    结合了原型式继承和组合继承的优点,是JavaScript中实现继承的一种最佳实践。

    function inheritParent(Parent, Child) {
      var F = function() {};
      F.prototype = Parent.prototype;
      Child.prototype = new F();
      Child.prototype.constructor = Child;
    }
    
    function Parent(name) {
      this.name = name;
    }
    
    function Child(name, age) {
      Parent.call(this, name);
      this.age = age;
    }
    
    inheritParent(Parent, Child);
    
    var child = new Child('Alice', 5);
    console.log(child.name); // 输出: Alice
    

在JavaScript中,ES6(ECMAScript 2015)引入了class关键字,提供了一种更接近传统面向对象编程语言的继承方式。使用class,我们可以定义类和它们之间的继承关系,语法更简洁,更易于理解。

以下是使用class实现继承的基本示例:

// 定义父类
class Parent {
  constructor(name) {
    this.name = name;
  }

  sayHello() {
    console.log(`Hello from ${this.name}`);
  }
}

// 定义子类,使用extends关键字继承父类
class Child extends Parent {
  constructor(name, age) {
    super(name); // 调用父类的构造函数
    this.age = age;
  }

  sayAge() {
    console.log(`Age: ${this.age}`);
  }
}

// 创建子类的实例
const child = new Child('Alice', 10);

// 调用继承的方法
child.sayHello(); // 输出: Hello from Alice
child.sayAge();   // 输出: Age: 10

在这个例子中,Child类通过extends关键字继承了Parent类。子类构造函数中使用super关键字调用父类的构造函数,以确保父类中的属性被正确初始化。

class语法是原型链继承的语法糖,它背后仍然使用原型链来实现继承。class语法提供了一种更清晰、更符合传统面向对象编程习惯的方式来定义类和继承。

使用class语法,我们还可以定义静态方法(使用static关键字),以及使用getset关键字定义访问器属性。

class Person {
  static count() {
    return Person.countNumber;
  }

  constructor(name) {
    this.name = name;
  }

  get age() {
    return this._age;
  }

  set age(value) {
    if (value > 0) {
      this._age = value;
    } else {
      console.log('Age must be a positive number.');
    }
  }
}

Person.countNumber = 0;

const alice = new Person('Alice');
alice.age = 30; // 设置属性值
console.log(alice.age); // 获取属性值: 30
console.log(Person.count()); // 静态方法调用: 0

在这个例子中,Person类有一个静态方法count和一个通过getset定义的访问器属性age。静态方法可以通过类本身调用,而不是类的实例。访问器属性允许我们控制对类属性的访问和赋值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值