Skip to content

原型

JavaScript 的原型(Prototype)是其面向对象编程的核心概念之一。理解原型对于掌握 JavaScript 的继承机制和对象模型至关重要。下面是对 JavaScript 原型的详细解释。

什么是原型?

在 JavaScript 中,每个函数都有一个 prototype 属性,这个属性是一个对象,包含可以被所有实例共享的方法和属性。当通过构造函数创建一个新对象时,该对象会隐式地链接到构造函数的 prototype 对象,从而能够访问 prototype 上定义的方法和属性。

[原型链]

每个对象都有一个内部属性 [[Prototype]],通常可以通过 __proto__ 访问(虽然这不是标准属性,但在大多数现代浏览器中都支持)。这个 [[Prototype]] 指向创建该对象的构造函数的 prototype 属性。这种链接关系形成了一个原型链,使得对象可以访问其原型上的方法和属性。

原型的基本用法

定义构造函数

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

在原型上添加方法

javascript
Person.prototype.greet = function () {
  console.log(
    "Hello, I'm " + this.name + " and I'm " + this.age + " years old."
  );
};

创建对象实例

javascript
const alice = new Person("Alice", 30);
alice.greet(); // 输出: Hello, I'm Alice and I'm 30 years old.

原型链的工作原理

  1. 查找属性

    • 当你尝试访问一个对象的属性或方法时,JavaScript 会首先在该对象自身查找。
    • 如果找不到,它会沿着原型链向上查找,直到找到该属性或方法,或者到达原型链的末端(即 null)。
  2. 修改原型

    • 修改构造函数的 prototype 属性会影响所有已创建和将来创建的对象实例。
javascript
Person.prototype.sayAge = function () {
  console.log("I'm " + this.age + " years old.");
};

const bob = new Person("Bob", 25);
bob.sayAge(); // 输出: I'm 25 years old.

原型链的示例

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

Person.prototype.greet = function () {
  console.log(
    "Hello, I'm " + this.name + " and I'm " + this.age + " years old."
  );
};

function Student(name, age, grade) {
  Person.call(this, name, age); // 调用父类构造函数
  this.grade = grade;
}

// 设置原型链
Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;

// 添加子类特有的方法
Student.prototype.study = function () {
  console.log("I'm studying in grade " + this.grade);
};

// 创建实例
const alice = new Student("Alice", 30, 10);

// 调用从父类继承的方法
alice.greet(); // 输出: Hello, I'm Alice and I'm 30 years old.

// 调用子类特有的方法
alice.study(); // 输出: I'm studying in grade 10

// 查看原型链
console.log(alice.__proto__ === Student.prototype); // true
console.log(Student.prototype.__proto__ === Person.prototype); // true
console.log(Person.prototype.__proto__ === Object.prototype); // true
console.log(Object.prototype.__proto__); // null

使用 Object.getPrototypeOfObject.setPrototypeOf

  • Object.getPrototypeOf(obj):获取对象 obj 的原型对象。
  • Object.setPrototypeOf(obj, prototype):设置对象 obj 的原型对象为 prototype
javascript
const obj = {};
const proto = { x: 10 };

Object.setPrototypeOf(obj, proto);
console.log(obj.x); // 输出: 10

总结

  • 原型 是 JavaScript 中实现继承和共享方法的一种机制。
  • 原型链 是一种对象之间的链接关系,使得对象可以访问其原型上的方法和属性。
  • 通过 prototype 属性,可以在构造函数的原型上添加方法和属性,这些方法和属性会被所有实例共享。
  • 使用 Object.create 可以创建一个新对象,并将其原型设置为指定的对象。
  • Object.getPrototypeOfObject.setPrototypeOf 提供了更安全的方式来获取和设置对象的原型。

理解原型和原型链是掌握 JavaScript 面向对象编程的关键。如果你有更多关于原型的具体问题或需要进一步的例子,请告诉我!

Released under the MIT License.