JavaScript 原型与原型链
本文档详细介绍了JavaScript中的原型与原型链,以及它们在前端开发中的应用。
概述
JavaScript是一种基于原型的语言,每个对象都有一个原型属性,通过原型链对象之间可以继承属性和方法。利用这个特性,可以实现对象继承和复用。
构造函数与原型
在JavaScript中,每个函数都有一个prototype
属性。这个属性是一个对象,所有通过这个函数创建的实例都会共享这个对象上的属性和方法。
示例代码
// 定义构造函数
function Person(name, age) {
this.name = name;
this.age = age;
}
// 在Person的原型上定义一个方法
Person.prototype.sayHello = function() {
console.log(`Hello, my name is ${this.name}, and I am ${this.age} years old.`);
};
// 创建Person的实例
const person1 = new Person('Alice', 25);
const person2 = new Person('Bob', 30);
// 调用实例方法
person1.sayHello(); // Hello, my name is Alice, and I am 25 years old.
person2.sayHello(); // Hello, my name is Bob, and I am 30 years old.
上述代码展示了如何通过构造函数和原型创建对象并定义共享方法。
原型链
当访问对象的属性时,JavaScript会首先查找对象自身的属性。如果找不到,它会去对象的原型(即__proto__
)上查找。这个过程称为原型链。
示例代码
console.log(person1.__proto__ === Person.prototype); // true
console.log(Person.prototype.__proto__ === Object.prototype); // true
console.log(Object.prototype.__proto__ === null); // true
原型链示意图
person1 -> Person.prototype -> Object.prototype -> null
在上述代码中,person1.__proto__
指向Person.prototype
,Person.prototype.__proto__
指向Object.prototype
,而Object.prototype.__proto__
是null
,表示原型链的顶端。
继承
JavaScript的原型链提供了继承的功能。可以通过修改原型链实现对象的继承。
示例代码
// 定义子类构造函数
function Employee(name, age, jobTitle) {
Person.call(this, name, age); // 调用父类构造函数
this.jobTitle = jobTitle;
}
// 设置Employee的原型为Person的实例
Employee.prototype = Object.create(Person.prototype);
// 纠正Employee的构造函数引用
Employee.prototype.constructor = Employee;
// 在Employee的原型上定义新方法
Employee.prototype.sayJobTitle = function() {
console.log(`I am a ${this.jobTitle}.`);
};
// 创建Employee的实例
const employee1 = new Employee('Charlie', 28, 'Developer');
// 调用父类和子类的方法
employee1.sayHello(); // Hello, my name is Charlie, and I am 28 years old.
employee1.sayJobTitle(); // I am a Developer.
上述代码展示了如何通过原型链实现继承。
ES6类语法
ES6引入了class
关键词,使得定义类和继承更加直观和简洁。
示例代码
// 定义Person类
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.`);
}
}
// 定义Employee类继承Person类
class Employee extends Person {
constructor(name, age, jobTitle) {
super(name, age); // 调用父类构造函数
this.jobTitle = jobTitle;
}
// 定义新方法
sayJobTitle() {
console.log(`I am a ${this.jobTitle}.`);
}
}
// 创建Employee实例
const employee1 = new Employee('Dave', 35, 'Designer');
// 调用父类和子类的方法
employee1.sayHello(); // Hello, my name is Dave, and I am 35 years old.
employee1.sayJobTitle(); // I am a Designer.
通过class
和extends
关键字,可以看出ES6提供了更简洁和清晰的语法来定义类和实现继承。