JavaScript 继承 超详细综合讲解(从原理到实战)

发布时间:2026/7/28 6:18:23

JavaScript 继承 超详细综合讲解(从原理到实战) JavaScript 是基于原型Prototype的语言它的继承和 Java、C 等基于类的语言完全不同。这篇会从核心原理、6 种继承方案、优缺点、ES6 继承全方位讲透新手也能完全看懂。一、先搞懂JS 继承的核心基石原型链要学会继承必须先理解 3 个核心概念构造函数用来创建对象的函数首字母大写原型对象prototype每个函数都有prototype属性指向共享方法/属性的对象__proto__每个对象都有的隐式属性指向它的原型继承的本质让一个对象的__proto__指向另一个对象从而访问另一个对象的属性和方法实现代码复用。二、JS 继承的 6 种经典方案从旧到新1. 原型链继承最基础核心思想将子类的原型对象直接指向父类的实例。// 父类functionParent(){this.name父类;this.arr[1,2,3];// 引用类型属性}Parent.prototype.sayfunction(){console.log(我是父类方法);};// 子类functionChild(){}// 核心子类原型 父类实例Child.prototypenewParent();// 测试constchild1newChild();constchild2newChild();child1.say();// 我是父类方法 ✅优点实现简单能继承父类属性 原型方法致命缺点引用类型属性会被所有实例共享修改一个全部改变child1.arr.push(4);console.log(child2.arr);// [1,2,3,4] ❌ 污染了其他实例创建子类实例时无法向父类构造函数传参2. 借用构造函数继承经典继承核心思想在子类构造函数中用call()/apply()调用父类构造函数。functionParent(name){this.namename;this.arr[1,2,3];}functionChild(name){// 核心借用父类构造函数绑定子类 this还能传参Parent.call(this,name);}constchild1newChild(小明);constchild2newChild(小红);child1.arr.push(4);console.log(child1.arr);// [1,2,3,4]console.log(child2.arr);// [1,2,3] ✅ 不共享console.log(child1.name);// 小明 ✅ 可传参优点解决了引用类型共享问题可以向父类传参缺点方法都定义在父类构造函数内无法复用每次创建实例都重新生成方法不能继承父类原型上的方法3. 组合继承最常用的经典方案核心思想结合原型链继承借用构造函数继承取长补短。functionParent(name){this.namename;this.arr[1,2,3];}Parent.prototype.sayfunction(){console.log(this.name);};functionChild(name,age){// 1. 借用构造函数继承属性 传参Parent.call(this,name);this.ageage;}// 2. 原型链继承原型方法Child.prototypenewParent();// 修正 constructor 指向必须加否则指向 ParentChild.prototype.constructorChild;// 测试constchildnewChild(小明,18);child.say();// 小明 ✅child.arr.push(4);优点融合了前两种的优点属性不共享可传参方法在原型上可复用是 ES6 之前最常用的继承方式缺点父类构造函数会被调用两次一次给原型一次实例化存在多余的父类实例属性4. 原型式继承核心思想不使用构造函数基于一个现有对象创建新对象类似Object.create。// 封装一个继承函数functioncreateObj(obj){functionF(){}F.prototypeobj;returnnewF();}// 父对象constparent{name:父亲,arr:[1,2,3]};// 继承constchildcreateObj(parent);优点适合简单对象继承无需定义构造函数缺点和原型链继承一样引用类型共享无法传参5. 寄生式继承核心思想在原型式继承基础上给新对象增加方法。functioncreateChild(obj){constchildObject.create(obj);// 增强对象child.sayfunction(){console.log(hello);};returnchild;}优点可以给继承的对象扩展方法缺点方法无法复用引用类型共享问题6. 寄生组合式继承最完美的 ES5 继承核心思想修复组合继承调用两次父类的问题只继承原型不调用父类构造函数给原型赋值。这是ES5 中最理想、最高效的继承方式。functionParent(name){this.namename;}Parent.prototype.sayfunction(){};functionChild(name){Parent.call(this,name);}// 核心只继承原型不实例化父类Child.prototypeObject.create(Parent.prototype);Child.prototype.constructorChild;优点只调用一次父类构造函数无多余属性原型链保持正常业界公认最佳 ES5 继承方案三、ES6 class 继承现在最常用ES6 用classextends关键字实现继承语法更简洁底层依然是寄生组合式继承。基础用法// 父类classParent{constructor(name){this.namename;}say(){console.log(this.name);}}// 子类继承classChildextendsParent{constructor(name,age){super(name);// 必须调用相当于 Parent.call(this)this.ageage;}}constchildnewChild(小明,18);child.say();// 小明 ✅关键规则必须在 constructor 第一行调用super()super既可以当函数调用父构造函数也可以当对象使用调用父方法继承后子类拥有父类所有属性和方法super 用法classChildextendsParent{parentSay(){super.say();// 调用父类的方法}}四、6 种继承方案对比总结继承方式优点缺点原型链继承实现简单可继承原型方法引用共享无法传参借用构造函数可传参引用不共享无法继承原型方法方法不能复用组合继承最常用属性方法都能继承父类构造调用两次原型式继承简单对象继承引用共享无法传参寄生式继承可扩展对象方法方法无法复用寄生组合式继承完美 ES5 继承高效无冗余语法稍复杂ES6 extends语法简洁语义清晰最推荐低版本 IE 不支持可 babel 编译五、高频面试题必看JS 继承的本质是什么基于原型链让对象通过__proto__访问另一个对象的属性和方法。class 继承和原型继承是什么关系class是语法糖底层依然是原型继承。为什么组合继承会调用两次父类一次new Parent()给子类原型一次Parent.call()给实例。最完美的 ES5 继承是寄生组合式继承。ES6 继承中super作用调用父类构造函数初始化this。总结JS 是原型继承不是类继承ES5 最优寄生组合式继承实际开发直接用ES6 class extends继承核心复用代码 原型链指向

相关新闻