js 实现原型
原型的基本概念
在JavaScript中,每个对象都有一个原型(prototype),原型本身也是一个对象。原型用于实现继承和共享属性。当访问一个对象的属性时,如果对象本身没有该属性,JavaScript会沿着原型链向上查找,直到找到该属性或到达原型链的顶端(null)。
原型链的实现
原型链是JavaScript实现继承的核心机制。通过原型链,对象可以访问其原型对象的属性和方法。以下是一个简单的原型链示例:
function Person(name) {
this.name = name;
}
Person.prototype.sayHello = function() {
console.log(`Hello, my name is ${this.name}`);
};
const person = new Person('Alice');
person.sayHello(); // 输出: Hello, my name is Alice
设置对象的原型
可以通过多种方式设置对象的原型:
1. 使用构造函数
构造函数通过prototype属性设置其实例的原型。所有通过该构造函数创建的实例都会共享同一个原型对象。
function Animal(type) {
this.type = type;
}
Animal.prototype.getType = function() {
return this.type;
};
const cat = new Animal('Cat');
console.log(cat.getType()); // 输出: Cat
2. 使用Object.create()
Object.create()方法创建一个新对象,并将传入的对象作为新对象的原型。
const proto = {
greet() {
console.log('Hello!');
}
};
const obj = Object.create(proto);
obj.greet(); // 输出: Hello!
3. 使用__proto__属性
__proto__属性(已弃用)可以直接设置对象的原型。建议使用Object.setPrototypeOf()替代。
const parent = {
value: 42
};
const child = {};
child.__proto__ = parent;
console.log(child.value); // 输出: 42
4. 使用Object.setPrototypeOf()
Object.setPrototypeOf()方法设置一个对象的原型为另一个对象。
const parent = {
value: 42
};
const child = {};
Object.setPrototypeOf(child, parent);
console.log(child.value); // 输出: 42
获取对象的原型
可以通过以下方法获取对象的原型:
1. 使用Object.getPrototypeOf()
Object.getPrototypeOf()方法返回指定对象的原型。
const proto = {};
const obj = Object.create(proto);
console.log(Object.getPrototypeOf(obj) === proto); // 输出: true
2. 使用__proto__属性
__proto__属性也可以用于获取对象的原型。
const proto = {};
const obj = Object.create(proto);
console.log(obj.__proto__ === proto); // 输出: 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.
注意事项
- 原型链不宜过长,否则会影响性能。
- 修改原型会影响所有继承自该原型的对象。
- 避免直接使用
__proto__属性,推荐使用Object.getPrototypeOf()和Object.setPrototypeOf()。







