js实现原型
原型的概念
在JavaScript中,每个对象都有一个原型(prototype),原型是一个对象,它包含可以由其他对象继承的属性和方法。原型机制是JavaScript实现继承的基础。
原型链
每个对象都有一个内部属性[[Prototype]],指向它的原型对象。当访问一个对象的属性时,如果对象本身没有该属性,JavaScript会沿着原型链向上查找,直到找到该属性或到达原型链的末端(null)。
创建原型的方法
使用构造函数
构造函数通过new关键字创建对象实例。构造函数的prototype属性会成为实例的原型。
function Person(name) {
this.name = name;
}
Person.prototype.greet = function() {
console.log(`Hello, my name is ${this.name}`);
};
const person = new Person('Alice');
person.greet(); // 输出: Hello, my name is Alice
使用Object.create()
Object.create()方法创建一个新对象,使用现有对象作为新对象的原型。
const personProto = {
greet: function() {
console.log(`Hello, my name is ${this.name}`);
}
};
const person = Object.create(personProto);
person.name = 'Alice';
person.greet(); // 输出: Hello, my name is Alice
使用ES6的class语法
ES6引入了class语法,简化了原型继承的写法。class实际上是构造函数的语法糖。
class Person {
constructor(name) {
this.name = name;
}
greet() {
console.log(`Hello, my name is ${this.name}`);
}
}
const person = new Person('Alice');
person.greet(); // 输出: Hello, my name is Alice
修改原型
可以通过修改构造函数的prototype属性来动态改变所有实例的行为。
function Person(name) {
this.name = name;
}
const person1 = new Person('Alice');
Person.prototype.greet = function() {
console.log(`Hello, my name is ${this.name}`);
};
person1.greet(); // 输出: Hello, my name is Alice
原型链的验证
可以使用instanceof运算符检查对象是否在某个构造函数的原型链上。
console.log(person1 instanceof Person); // 输出: true
也可以使用Object.getPrototypeOf()获取对象的原型。
console.log(Object.getPrototypeOf(person1) === Person.prototype); // 输出: true
原型继承的实现
通过组合构造函数和原型链可以实现继承。

function Animal(name) {
this.name = name;
}
Animal.prototype.speak = function() {
console.log(`${this.name} makes a noise.`);
};
function Dog(name) {
Animal.call(this, name);
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
Dog.prototype.speak = function() {
console.log(`${this.name} barks.`);
};
const dog = new Dog('Rex');
dog.speak(); // 输出: Rex barks.
注意事项
- 避免直接修改内置对象的原型(如
Array.prototype),这可能导致不可预期的行为。 - 原型链过长会影响性能,因为属性查找需要遍历整个链。
- 使用
Object.create(null)可以创建一个没有原型的对象,适合用作纯粹的字典。





