在JavaScript中,每个函数都有一个prototype属性,我们称之为“原型对象”。原型对象是一个普通的对象,它有自己的属性和方法。通常情况下,我们为了让某个函数变成一个构造函数,会将它的prototype属性设置为一个新对象。
例如,以下代码定义了一个构造函数Person,并将它的prototype属性设置为一个新对象,该对象有一个name属性和一个sayHello方法:
function Person(name) {
this.name = name;
}
Person.prototype = {
sayHello: function() {
console.log(`Hello, my name is ${this.name}`);
}
};
使用构造函数创建一个实例后,该实例的__proto__属性会指向构造函数的prototype属性:
const person = new Person('Alice');
console.log(person.__proto__ === Person.prototype); // true
每个JavaScript对象都有一个__proto__属性,用来指向它的原型对象。实际上,我们可以把原型对象想象为一个链表,每个链表节点都有一个指向父节点的指针,表示继承关系。因此,我们将整个继承链称为“原型链”。
例如,以下代码定义了一个学生对象,它继承自Person,并将它的prototype属性设置为Person的一个实例对象。在这个例子中,我们将原型链设置为:student -> Person.prototype -> Object.prototype -> null。
function Student(name, grade) {
Person.call(this, name);
this.grade = grade;
}
Student.prototype = Object.create(Person.prototype);
Student.prototype.sayGrade = function() {
console.log(`I am in grade ${this.grade}`);
};
const student = new Student('Bob', 3);
console.log(student.__proto__ === Student.prototype); // true
console.log(student.__proto__.__proto__ === Person.prototype); // true
console.log(student.__proto__.__proto__.__proto__ === Object.prototype); // true
console.log(student.__proto__.__proto__.__proto__.__proto__ === null); // true
在这个例子中,Student继承了Person的属性和方法,同时还定义了自己的sayGrade方法。当我们调用student.sayHello()时,它会在原型链上查找Person.prototype的sayHello方法,因此程序可以正常运行。
通过使用原型链,我们可以轻松地实现继承。在上面的例子中,我们定义了一个学生对象Student,它继承自Person,并添加了自己的sayGrade方法。
function Student(name, grade) {
Person.call(this, name);
this.grade = grade;
}
Student.prototype = Object.create(Person.prototype);
Student.prototype.sayGrade = function() {
console.log(`I am in grade ${this.grade}`);
};
这样就实现了一个“学生”类,它继承了“人”类的属性和方法。
原型对象中的方法是可以被多个实例共享的。例如,在以下代码中,我们定义了一个Person对象和两个Person的实例alice和bob。在Person的原型对象中,我们定义了一个sayHello方法,这个方法可以被所有Person实例共享。因此,无论是alice.sayHello()还是bob.sayHello(),它们的输出都是一样的。
function Person(name) {
this.name = name;
}
Person.prototype.sayHello = function() {
console.log(`Hello, my name is ${this.name}`);
};
const alice = new Person('Alice');
const bob = new Person('Bob');
alice.sayHello(); // "Hello, my name is Alice"
bob.sayHello(); // "Hello, my name is Bob"
JavaScript原型对象是语言中一个重要的概念,通过它,我们可以实现继承、共享方法等功能,同时也能更好地理解JavaScript的面向对象编程思想。