返回

前端基础教程:一文搞懂 JS 原型和原型链

前端

在 JavaScript 的世界里,万物皆对象。没错,一切都以对象的形式存在。这使得 JavaScript 成为一种灵活而强大的语言,可以轻松创建复杂的数据结构和代码结构。

对象、引用类型和原型

引用类型(也称为非原始类型)存储对存储在内存中的对象的引用。它们包括对象、数组、日期、正则表达式和函数。当你创建一个引用类型变量时,它将存储对实际对象的引用的值。这允许你通过引用变量来访问和操作该对象。

所有 JavaScript 对象都继承自一个称为 Object 的内置原型对象。这意味着所有对象都自动拥有 Object 原型中定义的方法和属性。

原型链

原型链是一个对象链,它允许对象访问其原型中的属性和方法。当对象尝试访问一个它不直接拥有的属性或方法时,JavaScript 会沿着原型链向上查找,直到找到该属性或方法。

例如,让我们创建一个 Person 对象:

const person = {
  name: "John Doe",
};

如果我们尝试访问 person 对象的 toString 方法,JavaScript 会沿着原型链向上查找,直到找到 Object 原型中的 toString 方法。

console.log(person.toString()); // [object Object]

使用原型链

原型链允许我们创建可重用的代码,并轻松扩展对象的 functionality。例如,我们可以向 Person 原型中添加一个 greet 方法:

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

现在,所有 Person 对象都可以使用 greet 方法:

person.greet(); // Hello, my name is John Doe

修改原型

我们也可以修改原型对象来添加或更改方法和属性。例如,我们可以向 Object 原型中添加一个 isPrototypeOf 方法,以检查一个对象是否为另一个对象的原型:

Object.prototype.isPrototypeOf = function(object) {
  while (object) {
    if (object === this) {
      return true;
    }
    object = Object.getPrototypeOf(object);
  }
  return false;
};

现在,我们可以检查 person 对象是否为 Object 原型的后代:

console.log(Object.prototype.isPrototypeOf(person)); // true

创建自定义原型

除了使用内置的 Object 原型之外,我们还可以创建自定义原型。这允许我们创建具有特定属性和方法的新对象类型。

例如,我们可以创建一个 Animal 原型:

function Animal(name) {
  this.name = name;
}

Animal.prototype.eat = function() {
  console.log(`${this.name} is eating.`);
};

然后,我们可以使用 Animal 原型来创建 Dog 对象:

const dog = new Animal("Buddy");

现在,dog 对象拥有 Animal 原型的所有方法和属性:

dog.eat(); // Buddy is eating.

结论

原型和原型链是 JavaScript 中强大的概念,它们允许我们创建灵活且可扩展的代码。通过理解这些概念,你可以充分利用 JavaScript 的面向对象功能,并编写更强大和更有效的代码。