一、核心概念
每个对象(Object)都有一个私有属性指向另一个名为原型(prototype)的对象。原型对象也有一个自己的原型,层层向上直到一个对象的原型为 null。根据定义,null 没有原型,并作为这个原型链(prototype chain)中的最后一个环节。
-
prototype属性:每个函数都有的属性,指向原型对象
-
__proto__属性:每个实例对象都有的属性,指向构造函数的原型
-
constructor属性:原型对象指向构造函数的引用
二、原型链验证方法
function Person(name) {this.name = name;}const jack = new Person('Jack');// 验证原型关系console.log(jack.__proto__ === Person.prototype); // trueconsole.log(Person.prototype.__proto__ === Object.prototype); // trueconsole.log(Object.prototype.__proto__ === null); // true// 原型链检测console.log(jack instanceof Person); // trueconsole.log(jack instanceof Object); // trueconsole.log(Person.prototype.isPrototypeOf(jack)); // true
三、原型链查找机制
function Animal() {this.type = '生物';}Animal.prototype.breathe = function() {return "正在呼吸";};function Dog() {this.sound = '汪汪';}// 设置原型继承Dog.prototype = new Animal();Dog.prototype.constructor = Dog;const myDog = new Dog();console.log(myDog.breathe()); // 通过原型链查找到Animal原型的方法console.log(myDog.hasOwnProperty('breathe')); // false
四、完整的原型链结构
-
实例对象
myDog -
Dog.prototype(包含Animal实例)
-
Animal.prototype
-
Object.prototype
-
null
-
五、如何实现继承
// 父类function Vehicle(wheels) {this.wheels = wheels || 0;}Vehicle.prototype.move = function() {return `正在移动,有 ${this.wheels} 个轮子`;};// 子类function Car() {Vehicle.call(this, 4); // 继承实例属性this.brand = '未知';}// 设置原型链Car.prototype = Object.create(Vehicle.prototype);Car.prototype.constructor = Car;// 添加子类方法Car.prototype.honk = function() {return '嘟嘟!';};const myCar = new Car();console.log(myCar.move()); // 继承父类方法
六、ES6 class语法糖
class Shape {constructor(color) {this.color = color;}draw() {return `绘制${this.color}的图形`;}}class Circle extends Shape {constructor(color, radius) {super(color);this.radius = radius;}area() {return Math.PI * this.radius ** 2;}}const redCircle = new Circle('red', 5);console.log(redCircle.draw()); // 继承父类方法
七、注意事项
1.原型污染问题:修改内置对象原型需谨慎
// 不推荐的做法Array.prototype.sum = function() {return this.reduce((a, b) => a + b, 0);};
2.性能优化:过长的原型链会影响查找效率
-
3.对象创建方式:
-
Object.create()直接指定原型 -
new操作符创建实例 -
4.现代替代方案:考虑使用组合代替继承
-
-
八、调试技巧
-
使用控制台查看原型链:
console.dir(myCar);
检查属性来源:
-
console.log(Object.getOwnPropertyNames(myCar));console.log(myCar.hasOwnProperty('wheels'));
总结
-
1.优先使用ES6 class语法
-
2.避免超过3层的原型链继承
-
3.使用组合模式替代复杂继承
-
4.始终在继承时修正constructor指向
![]() |
Austin Liu 刘恒辉
Project Manager and Software Designer E-Mail:lzhdim@163.com Blog:https://lzhdim.cnblogs.com 欢迎收藏和转载此博客中的博文,但是请注明出处,给笔者一个与大家交流的空间。谢谢大家。 |




浙公网安备 33010602011771号