构造函数和原型对象
在js中,可以通过函数来创造对象,每个函数都有一个prototype
属性,该属性是一个对象。所有通过该构造函数创造出来的对象,都可以共享prototype
上的属性以及方法。
function Person(name) {
this.name = name;
}
Person.prototype.sayHello = function() {
console.log('Hello, my name is ' + this.name);
};
const alice = new Person('Alice');
alice.sayHello(); // 输出: Hello, my name is Alice
可以在上面的例子中看到,在构造函数中并没有sayHello
方法,后面通过在Person的prototype
上来创造一个方法,后续实例化对象之后就可以调用该方法了。
__proto__
属性
每个JavaScript对象都有一个__proto__
属性,这个属性指向对象的原型,也就是构造函数的prototype
属性。当我们访问一个对象的属性时,如果该属性不存在,JavaScript会查找该对象的__proto__
链,直至找到该属性,或者到达链的末尾。
console.log(alice.__proto__ === Person.prototype); // 输出: true
继承
使用原型链可以实现js上的继承
function Animal() {
this.species = 'Animal';
}
Animal.prototype.makeSound = function() {
console.log('Some generic sound');
};
function Dog(name) {
this.name = name;
}
// 让 Dog 的原型指向 Animal 的实例,从而实现继承
Dog.prototype = new Animal();
Dog.prototype.constructor = Dog; // 修正 constructor 属性
Dog.prototype.bark = function() {
console.log('Woof! Woof!');
};
const dog = new Dog('Buddy');
console.log(dog.species); // 输出: Animal
dog.makeSound(); // 输出: Some generic sound
dog.bark(); // 输出: Woof! Woof!
Object 原型
所有对象的原型链最终都指向Object.prototype
,如果在原型链中都找不到方法,最终会返回undefined
console.log(dog.toString()); // 输出: [object Object]
console.log(dog.__proto__.__proto__ === Object.prototype); // 输出: true
console.log(Object.prototype.__proto__ === null); // 输出: true
显示原型链
指的是构造函数上的prototype
属性
function Person(name) {
this.name = name;
}
Person.prototype.sayHello = function() {
console.log('Hello, my name is ' + this.name);
};
const alice = new Person('Alice');
Person
创造出来的所有对象共享Person.prototype
上的属性和方法
隐式原型链
指的是对象上的__proto__
属性,这是创造对象时,js引擎自动设置的,指向创造这个对象的构造函数上的prototype
属性。
function Animal() {
this.species = 'Animal';
}
Animal.prototype.makeSound = function() {
console.log('Some generic sound');
};
function Dog(name) {
this.name = name;
}
// 让 Dog 的显式原型指向 Animal 的实例,从而实现继承
Dog.prototype = new Animal();
Dog.prototype.constructor = Dog; // 修正 constructor 属性
Dog.prototype.bark = function() {
console.log('Woof! Woof!');
};
const buddy = new Dog('Buddy');
Dog.prototype
是显示原型链
buddy.__proto__
是隐式原型链,指向Dog.prototype
console.log(Dog.prototype); // 显式原型链
console.log(buddy.__proto__); // 隐式原型链,指向 Dog.prototype
console.log(buddy.__proto__ === Dog.prototype); // 输出: true
console.log(Dog.prototype.__proto__ === Animal.prototype); // 输出: true
console.log(Animal.prototype.__proto__ === Object.prototype); // 输出: true
console.log(Object.prototype.__proto__ === null); // 输出: true