返回

JS对原型和原型链以及继承的解读与理解

前端

JavaScript是基于原型的语言,这意味着对象的行为和属性是由其原型决定的。原型本身也是一个对象,它的原型是Object.prototype。因此,所有的JavaScript对象都继承了Object.prototype的方法和属性。

每个对象都有一个内部属性prototype,指向其构造函数的原型对象。原型链是指从一个对象一直到Object.prototype的原型对象构成的链条。当一个对象访问一个属性或方法时,JavaScript引擎会沿着原型链查找,直到找到该属性或方法。

对象创建过程

在JavaScript中,创建对象有两种方式:

  • 使用new操作符调用构造函数。
  • 使用对象字面量语法。

使用new操作符调用构造函数时,JavaScript引擎会执行以下步骤:

  1. 创建一个新对象。
  2. 将新对象的原型属性设置为构造函数的原型对象。
  3. 执行构造函数,并将this指向新对象。

使用对象字面量语法创建对象时,JavaScript引擎会执行以下步骤:

  1. 创建一个新对象。
  2. 将新对象的原型属性设置为Object.prototype。

继承

继承是指从一个对象继承属性和方法的能力。在JavaScript中,继承是通过原型链实现的。当一个对象访问一个属性或方法时,JavaScript引擎会沿着原型链查找,直到找到该属性或方法。

经典继承

经典继承是通过使用Object.create()方法实现的。Object.create()方法接受两个参数:

  • 一个对象,作为新对象的原型。
  • 一个可选的对象,作为新对象的属性。

例如,以下代码创建一个名为Child的类,该类继承自Parent类:

function Parent() {
  this.name = "Parent";
}

Parent.prototype.getName = function() {
  return this.name;
};

function Child() {
  this.age = 10;
}

Child.prototype = Object.create(Parent.prototype);

Child.prototype.getAge = function() {
  return this.age;
};

const child = new Child();

console.log(child.getName()); // "Parent"
console.log(child.getAge()); // 10

组合继承

组合继承是通过使用原型链和对象字面量语法实现的。组合继承结合了经典继承和原型式继承的优点。

例如,以下代码创建一个名为Child的类,该类继承自Parent类:

function Parent() {
  this.name = "Parent";
}

Parent.prototype.getName = function() {
  return this.name;
};

function Child() {
  Parent.call(this);
  this.age = 10;
}

Child.prototype = Object.create(Parent.prototype);

Child.prototype.getAge = function() {
  return this.age;
};

const child = new Child();

console.log(child.getName()); // "Parent"
console.log(child.getAge()); // 10

原型式继承

原型式继承是通过直接将一个对象的原型设置为另一个对象的实现的。原型式继承是一种简单而有效的继承方式。

例如,以下代码创建一个名为Child的类,该类继承自Parent类:

function Parent() {
  this.name = "Parent";
}

Parent.prototype.getName = function() {
  return this.name;
};

function Child() {
  this.age = 10;
}

Child.prototype = Parent.prototype;

const child = new Child();

console.log(child.getName()); // "Parent"
console.log(child.getAge()); // 10

原型委托

原型委托是原型式继承的一种特殊形式。在原型委托中,一个对象并不直接继承另一个对象的原型。相反,它委托另一个对象来处理其原型属性的访问。

例如,以下代码创建一个名为Child的类,该类继承自Parent类:

function Parent() {
  this.name = "Parent";
}

Parent.prototype.getName = function() {
  return this.name;
};

function Child() {
  this.age = 10;
}

Child.prototype = {
  getName: function() {
    return Parent.prototype.getName.call(this);
  }
};

const child = new Child();

console.log(child.getName()); // "Parent"
console.log(child.getAge()); // 10

面向对象

面向对象是将对象作为编程的基本单元的一种编程范式。面向对象编程的特点是:

  • 封装:将数据和行为封装在对象中。
  • 继承:从现有对象创建新对象。
  • 多态:对象能够对相同的消息做出不同的响应。

JavaScript并不是严格的面向对象语言,但它支持面向对象编程。JavaScript中的对象是面向对象的,但它没有类和接口的概念。JavaScript中的继承是通过原型链实现的。