JavaScript 原型

2023-10-30 09:09:50 浏览数 (2)

在 JavaScript 中,函数也是一种对象。每个函数都有一个特殊的属性,叫做 prototype。这个属性实际上就是一个普通的对象,它拥有一些方法和属性,那么这些方法和属性是如何被其他对象共享的呢?这就是 JavaScript 的原型机制做的事情。

我们可以通过构造函数来创建一个对象,假如我们创建了一个对象 a,那么它就有一个 proto 属性。这个 proto 属性就指向了该构造函数的 prototype 属性,也就是原型对象。

代码语言:javascript复制
function Person(name) {
  this.name = name;
}
Person.prototype.sayHello = function () {
  console.log("Hello! My name is "   this.name);
}
var a = new Person("Zhang San");
a.sayHello(); // Hello! My name is Zhang San

我们在创建 Person 对象的时候,其实就是在创建一个实例对象,并且将这个实例对象的 proto 属性指向了 Person.prototype。而 sayHello 方法就是在原型对象中定义的,因此它并不会通过继承的方式被复制到每个实例对象中,而是通过原型链的方式被实例对象共享。

JavaScript 原型链

借助 JavaScript 的原型机制,我们甚至可以通过多层继承去达到我们想要的目的,这就是 JavaScript 的原型链。

代码语言:javascript复制
function Person(name) {
  this.name = name;
}
Person.prototype.sayHello = function () {
  console.log("Hello! My name is "   this.name);
}

function Student(name, age) {
  Person.call(this, name);
  this.age = age;
}
Student.prototype = Object.create(Person.prototype);
Student.prototype.sayAge = function () {
  console.log("My age is "   this.age);
}

var tom = new Student("tom", 18);
tom.sayHello(); // Hello! My name is tom
tom.sayAge(); // My age is 18

我们首先定义了一个 Person 构造函数,并将其原型对象上添加了 sayHello 方法。接着我们定义了一个 Student 构造函数,继承于 Person 构造函数。在 Student 构造函数中,我们通过 Person.call(this, name) 的方式来继承父类的实例属性。接着,我们将 Student 的原型对象 prototype 设置为一个空对象,然后通过 Object.create(Person.prototype) 将 Student 对象的原型对象与 Person 对象的原型对象连接起来,从而建立了原型链。最后,我们在 Student 的原型对象中添加了 sayAge 方法。

在创建 tom 对象的时候,其实就是在创建了一个 Student 的实例,并且将 tom 对象的 proto 属性指向了 Student.prototype。由于 Student.prototype 又是一个空对象,并且它的 proto 属性指向了 Person.prototype,所以当我们调用 tom.sayHello() 的时候,其实就是在调用 Person.prototype 的 sayHello 方法。而当我们调用 tom.sayAge() 的时候,就是在调用 Student.prototype 的 sayAge 方法了。

综上所述,JavaScript 中的原型和原型链是用于实现继承和属性共享的一种机制,它不仅使得代码更容易维护,而且可以节省内存。同时,JavaScript 原型链还允许我们通过多层继承建立非常灵活的对象模型。

邀请人:堕落飞鸟

0 人点赞