如何理解原型及原型链?js的继承方式

原型与原型链

  1. 原型
    在js中,每个对象都有一个原型(prototype)。原型是一个对象,其他对象可以通过原型来共享属性和方法。当我们创建一个对象时,它会自动关联到一个原型对象。
    例如:
    function Person(name, age) {
    this.name = name;
    this.age = age;
    }
    
    // 在 Person 构造函数的原型上添加一个 greet 方法
    Person.prototype.greet = function() {
    console.log(`Hello, my name is ${this.name}.`);
    };
    
    const person1 = new Person('Alice', 30);
    const person2 = new Person('Bob', 25);
    
    person1.greet(); // 输出 "Hello, my name is Alice."
    person2.greet(); // 输出 "Hello, my name is Bob."
    
    在上面的代码中,创建了一个Person对象,有通过person创建了person1和person2对象,这两个对象都关联到 Person.prototype 原型对象,并且可以共享 greet 方法。
  2. 原型链
    原型链是福哦个对象通过原型链条连接在一起的数据结构。当访问一个对象的属性或方法时,js引擎会先在对象本身中寻找,如果找不到,就会沿着原型链继续找,知道找到该属性或方法,或者达到原型链的顶端(Object.prototype )。
    举个例子:
function Person(name, age) {
  this.name = name;
  this.age = age;
}

Person.prototype.greet = function() {
  console.log(`Hello, my name is ${this.name}.`);
};

const person1 = new Person('Alice', 30);

console.log(person1.toString()); // 输出 "[object Object]"

在这个例子中 person1通过原型链继承了toString方法。
所以是Object.prototype原型链的顶端,它是所有对象的原型,包括内置对象和自定义对象。当查找属性或方法时,原型链会一直往上查找,直到 Object.prototype。如果在整个原型链上都找不到该属性或方法,则返回 undefined

原型链继承

原型继承是通过原型链来实现对象间的属性和方法共享。在原型继承中,一个对象可以从另一个对象继承属性和方法,这样可以实现对象之间的复用和扩展。

原型继承的基本概念如下:

  1. 每个 JavaScript 对象都有一个原型对象(prototype),它是一个普通对象。
  2. 当访问一个对象的属性或方法时,如果该对象本身没有该属性或方法,JavaScript 引擎会沿着原型链向上查找,直到找到为止。
  3. 原型链是由多个对象通过原型关联形成的链条,最终的原型对象通常是 Object.prototype,它是 JavaScript 中所有对象的原型。
  4. 如果在整个原型链上都找不到该属性或方法,则返回 undefined

在原型继承中,我们可以通过构造函数的原型对象来共享属性和方法。当使用 new 关键字调用构造函数创建对象时,新对象会关联到该构造函数的原型,从而继承原型上的属性和方法。

下面是一个使用原型继承的简单示例:

// 定义一个 Person 构造函数
function Person(name) {
  this.name = name;
}

// 在 Person 的原型上添加一个 greet 方法
Person.prototype.greet = function() {
  console.log(`Hello, my name is ${this.name}.`);
};

// 使用 Person 构造函数创建两个对象
const person1 = new Person('Alice');
const person2 = new Person('Bob');

// 调用对象的 greet 方法
person1.greet(); // 输出 "Hello, my name is Alice."
person2.greet(); // 输出 "Hello, my name is Bob."

在上面的代码中,Person 构造函数的原型对象上有一个 greet 方法,通过 new Person() 创建的对象(例如 person1person2)会共享这个方法。这样,我们可以通过原型继承在多个对象之间共享方法,提高代码的重用性和可维护性。

需要注意的是,原型继承只能继承原型上的属性和方法,而不能继承构造函数内部的局部变量。如果需要更灵活的继承方式,可以考虑其他方式,例如组合继承、原型式继承、寄生式继承等。

js的其他继承方式

  1. 组合继承
    组合继承时结合了原型链继承和构造函数继承的一种继承方式。他通过在给子类的构造函数中调用父类的构造函数来继承父类的属性,并通过将子类的原型指向一个新的创建的父类对象来继承的方法。
function Parent(name) {
  this.name = name;
}

Parent.prototype.greet = function() {
  console.log(`Hello, my name is ${this.name}.`);
};

function Child(name, age) {
  Parent.call(this, name); // 构造函数继承
  this.age = age;
}

Child.prototype = Object.create(Parent.prototype); // 原型链继承
Child.prototype.constructor = Child;

const child = new Child('Alice', 5);
child.greet(); // 输出 "Hello, my name is Alice."

  1. 寄生式继承
    寄生式继承是在原型式的基础上增强新对象,添加额外的属性和方法。
function createPerson(proto, age) {
  const newPerson = createObject(proto); // 原型式继承
  newPerson.age = age; // 增强对象
  newPerson.introduce = function() {
    console.log(`I am ${this.name} and I am ${this.age} years old.`);
  };
  return newPerson;
}

const person = {
  name: 'Alice',
  greet: function() {
    console.log(`Hello, my name is ${this.name}.`);
  }
};

const newPerson = createPerson(person, 30);
newPerson.greet(); // 输出 "Hello, my name is Alice."
newPerson.introduce(); // 输出 "I am Alice and I am 30 years old."

  1. 寄生组合式继承
    寄生组合式继承是对组合继承的一种优化,通过构造函数继承属性,同时利用Object.create()方法来继承原型,避免了调用父类构造函数时产生的不必要的属性重复赋值问题。
function Parent(name) {
  this.name = name;
}

Parent.prototype.greet = function() {
  console.log(`Hello, my name is ${this.name}.`);
};

function Child(name, age) {
  Parent.call(this, name); // 构造函数继承
  this.age = age;
}

Child.prototype = Object.create(Parent.prototype); // 原型链继承
Child.prototype.constructor = Child;

const child = new Child('Alice', 5);
child.greet(); // 输出 "Hello, my name is Alice."

  1. 构造函数式继承
function Animal(name) {
  this.name = name;
}

function Dog(name, breed) {
  Animal.call(this, name);
  this.breed = breed;
}

const dog = new Dog('Buddy', 'Golden Retriever');
console.log(dog.name); // 输出 "Buddy"

你可能感兴趣的:(javascript,原型模式,开发语言,原型链,js继承)