返回

对象原型:从例子入手,轻松理解原型链

前端

认识原型链

我们用一个例子来理解原型链。

function Person(name, age) {
  this.name = name;
  this.age = age;
}

Person.prototype.sayHello = function() {
  console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
};

const person1 = new Person('John Doe', 25);

在这个例子中,Person 就是一个构造函数,person1Person 构造函数的一个实例对象。

原型的作用

现在来分析一下这段代码。

  • Person.prototypePerson 构造函数的原型对象。
  • person1.__proto__person1 实例对象的原型对象。
  • Person.prototypeperson1.__proto__ 是指向同一个对象的引用。

这意味着 person1 实例对象可以访问 Person.prototype 中的所有属性和方法。

原型链的查找过程

当我们访问 person1.sayHello() 时,会发生以下查找过程:

  1. 首先,在 person1 对象中查找 sayHello() 方法。
  2. 如果在 person1 对象中找不到 sayHello() 方法,则会沿着原型链向上查找。
  3. Person.prototype 中找到了 sayHello() 方法。
  4. 因此,person1 实例对象可以调用 sayHello() 方法。

原型链的继承

原型链还允许我们实现继承。

function Student(name, age, major) {
  Person.call(this, name, age);
  this.major = major;
}

Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;

const student1 = new Student('Jane Doe', 22, 'Computer Science');

在这个例子中,Student 构造函数继承了 Person 构造函数。

  • Student.prototype = Object.create(Person.prototype); 这行代码将 Person.prototype 作为 Student.prototype 的原型对象。
  • Student.prototype.constructor = Student; 这行代码将 Student 构造函数作为 Student.prototype 的构造函数。

这意味着 student1 实例对象可以访问 Person.prototypeStudent.prototype 中的所有属性和方法。

ES6的实例扩展语法

ES6 引入了实例扩展语法,使得我们能够更加方便地扩展实例对象。

class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  sayHello() {
    console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
  }
}

class Student extends Person {
  constructor(name, age, major) {
    super(name, age);
    this.major = major;
  }
}

const student1 = new Student('Jane Doe', 22, 'Computer Science');

在这个例子中,Student 类继承了 Person 类。

  • super(name, age); 这行代码调用了 Person 类的构造函数。
  • this.major = major; 这行代码将 major 属性添加到 student1 实例对象。

这意味着 student1 实例对象可以访问 Person.prototypeStudent.prototype 中的所有属性和方法。

总结

原型链是一个强大的机制,允许我们创建复杂的对象模型。

  • 原型链允许我们共享代码并实现继承。
  • ES6 的实例扩展语法使我们能够更加方便地扩展实例对象。

更多资源