JavaScript面向对象之Prototypes和继承
JavaScript是一门支持面向对象编程的语言,原型(prototype)是JavaScript中非常重要的一个概念。在这篇文章中,我们将讲解JavaScript中的原型、原型链以及如何使用原型实现继承。
1. 构造函数与原型
在JavaScript中,每个函数都有一个prototype属性,这个属性指向了一个对象,我们称之为原型对象。
比如下面这个例子中:
function Person(name) {
this.name = name;
}
Person.prototype.sayName = function() {
console.log('My name is ' + this.name);
}
var person = new Person('Tom');
在这个例子中,Person就是一个构造函数,person是一个对象实例。构造函数的原型对象Person.prototype上添加了一个方法sayName,那么person对象实例在执行sayName时,就可以找到它的原型链上的Person.prototype对象的sayName方法,从而成功执行。
2. 原型链
那么什么是原型链呢?实际上,每个对象实例都有一个__proto__属性,它指向了该对象的构造函数的原型对象,构成了一个原型链。如果我们在一个对象上找不到某个属性或者方法,JavaScript就会从原型链上继续往上查找,直到找到为止。
那么我们来看下面这个例子:
function Person(name) {
this.name = name;
}
Person.prototype.sayName = function() {
console.log('My name is ' + this.name);
}
function Student(name, grade) {
Person.call(this, name);
this.grade = grade;
}
// 这里需要将原型链指向Person.prototype,然后再定义新的方法
Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;
Student.prototype.sayGrade = function() {
console.log('My grade is ' + this.grade);
}
var student = new Student('Tom', 3);
在这个例子中,我们定义了一个Person构造函数和一个Student构造函数,Student构造函数继承于Person构造函数。那么在Student的原型链中,先是Student.prototype,然后是Person.prototype,最后是Object.prototype。
因此当我们调用student.sayName时,JavaScript先在student对象上查找,发现没有该方法,于是它会去在student.__proto__指向的Person.prototype中查找,找到了该方法之后,就可以成功执行了。而当我们调用student.sayGrade时,student对象上就会直接找到该方法,从而成功执行。
3. 示例说明
接下来,我们将通过两个示例分别说明如何使用原型和原型链进行继承。
示例1:原型继承
在JavaScript中,我们可以使用原型对象进行继承。比如下面这个例子中:
function Person(name) {
this.name = name;
}
Person.prototype.sayName = function() {
console.log('My name is ' + this.name);
}
function Student(name, grade) {
Person.call(this, name);
this.grade = grade;
}
Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;
var student = new Student('Tom', 3);
student.sayName();
在这个例子中,我们首先定义了一个Person构造函数,然后在Student构造函数中调用了Person的构造函数,从而继承它的属性。接着我们将Student构造函数的原型对象指向了Person的原型对象,从而实现了继承Person原型对象上的方法。
最后,在实例化一个student对象后,我们可以成功调用继承了来自Person的原型对象的sayName方法。
示例2:组合继承
在JavaScript中,我们还可以使用组合继承的方式进行继承,如下面这个例子:
function Person(name) {
this.name = name;
}
Person.prototype.sayName = function() {
console.log('My name is ' + this.name);
}
function Student(name, grade) {
Person.call(this, name);
this.grade = grade;
}
Student.prototype = new Person();
Student.prototype.constructor = Student;
var student = new Student('Tom', 3);
student.sayName();
在这个例子中,我们也定义了一个Person构造函数和一个Student构造函数。不同的是,在Student构造函数中,我们使用Person.call(this, name)继承了Person构造函数的属性,并通过将Student.prototype指向new Person()来继承了Person构造函数的原型对象。
最后,在实例化一个student对象后,通过调用sayName方法,我们同样可以成功访问继承来自Person的原型对象的sayName方法。
至此,我们已经讲解了JavaScript中的原型和原型链,并通过两个示例分别说明了如何使用原型和原型链进行继承。通过对原型和原型链的深入理解,我们可以更好地理解和设计JavaScript中的面向对象程序。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JavaScript面向对象之Prototypes和继承 - Python技术站