彻底搞懂JS原型链与继承底层原理
2026/9/14 21:27:55 网站建设 项目流程

刷过前端面试的同学都知道,原型链和继承是JS面试的必考题,也是很多人的知识盲区。大部分开发者平时只会用ES6的class继承,但问到原型链底层、属性查找机制、继承的区别与弊端时,很容易一问三不知。

其实JavaScript并不像Java、C++是真正的面向类的语言,它是基于原型的面向对象语言。JS中没有类的本质,class只是语法糖,所有的继承、方法复用,底层全部依靠原型链实现。今天我结合面试高频问题,带大家深挖原型链底层原理,彻底搞懂JS继承的核心机制,轻松应对面试手撕代码场景。

一、先搞懂核心:原型、原型对象、原型指针

想要吃透原型链,首先要分清三个基础概念:构造函数、原型对象、实例对象。每一个构造函数都自带prototype属性,也就是显式原型,指向它的原型对象;每一个实例对象都自带__proto__属性,也就是隐式原型,指向构造函数的原型对象。

我们日常定义的方法、公共属性,挂载在prototype上,就能被所有实例共享,这也是JS实现代码复用的基础。下面用一段基础代码直观演示三者关系:

// 定义构造函数 function Person(name, age) { this.name = name; this.age = age; } // 给原型对象挂载公共方法 Person.prototype.sayHello = function() { console.log(`我是${this.name},今年${this.age}岁`); } // 创建实例 const p1 = new Person('张三', 20); const p2 = new Person('李四', 22); // 验证原型指向 console.log(p1.__proto__ === Person.prototype); // true console.log(Person.prototype.constructor === Person); // true // 实例调用原型方法 p1.sayHello(); // 我是张三,今年20岁 p2.sayHello(); // 我是李四,今年22岁

从代码可以清晰看出:所有实例的隐式原型,都统一指向构造函数的显式原型,原型上的方法可以被所有实例共享,避免了每个实例都创建一份重复方法的内存浪费。

二、原型链到底是什么?属性查找底层机制

简单来说,原型链就是实例对象的__proto__层层向上查找形成的链式结构。当我们访问一个对象的属性或方法时,JS引擎会执行一套固定的查找规则,这也是原型链的核心底层逻辑。

查找规则分为三步:首先在当前实例对象自身查找,找到直接使用;如果没找到,就通过__proto__去原型对象上查找;依然没找到,就继续向上查找,直到找到顶层的Object.prototype,最终终点为null,查找结束。

// 延续上面的Person构造函数 console.log(p1.toString()); // 验证原型链终点 console.log(Person.prototype.__proto__ === Object.prototype); // true console.log(Object.prototype.__proto__); // null

三、面试重点:基于原型链实现原生继承

ES6 class继承本质是原型链继承的语法糖,面试中经常会要求

我们通过子类Student继承父类Person,手写组合继承,解决单一继承的弊端:

// 父类构造函数 function Person(name, age) { this.name = name; this.age = age; this.hobby = ['读书', '运动']; } Person.prototype.sayHello = function() { console.log(`我是${this.name}`); } // 子类构造函数 function Student(name, age, score) { // 构造函数继承:继承父类实例属性 Person.call(this, name, age); this.score = score; } // 原型链继承:继承父类原型方法 Student.prototype = new Person(); // 修正constructor指向 Student.prototype.constructor = Student; // 子类自定义方法 Student.prototype.showScore = function() { console.log(`我的成绩是${this.score}分`); } // 测试 const stu = new Student('小明', 18, 95); stu.sayHello(); // 我是小明 stu.showScore(); // 我的成绩是95分 console.log(stu.hobby); // ['读书', '运动']

组合继承结合了构造函数继承和原型链继承的优点,既解决了原型链继承引用属性共享篡改的问题,又完美继承了父类的原型方法,是ES5中最完善的继承方案。

四、ES6 Class继承与原型链的关系

很多初学者误以为ES6 class是全新的继承机制,其实它只是对原型链继承的封装,底层逻辑完全不变,只是写法更简洁、语义更强。

class Person { constructor(name, age) { this.name = name; this.age = age; } sayHello() { console.log(`我是${this.name}`); } } // class继承 class Student extends Person { constructor(name, age, score) { super(name, age); // 等价于Person.call(this) this.score = score; } } const stu = new Student('小红', 17, 98); stu.sayHello();

代码中的super本质就是调用父类构造函数,和ES5的call原理一致。class继承依然依托原型链实现方法复用,只是帮我们自动修正了原型指向和constructor,省去了手动配置的繁琐。

五、面试高频总结:原型链核心考点

结合多年面试经验,原型链相关面试题核心考点就3点:一是理解原型链的查找机制,二是能区分各种继承的优缺点,三是明白class语法糖的底层原理。

简单总结核心要点:JS所有对象都有原型,原型层层嵌套形成原型链;属性逐级向上查找,顶层为Object原型,终点为null;ES5组合继承解决了单一继承的缺陷,ES6 class继承是原型链的语法糖,底层依然依托原型链实现继承。

结尾

原型链是JavaScript的灵魂,也是前端进阶、面试的核心知识点。很多高级用法,比如防抖节流封装、组件继承、对象方法复用,底层都离不开原型链机制。彻底吃透原型链和继承底层,不仅能轻松应对面试,更能帮我们写出更优雅、更高效的JS代码。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询