南京淄博网站建设方案eclipse开发网站开发

张小明 2026/1/9 8:57:09
南京淄博网站建设方案,eclipse开发网站开发,wordpress 个人简介栏,华为云和wordpressJavaScript 原型与继承终极指南#xff1a;从原理到实战#xff08;2025 版#xff09; 原型与继承是 JavaScript 的核心灵魂#xff0c;也是前端面试的 “高频重灾区”。很多开发者深陷 “原型链迷宫”#xff0c;仅停留在 “__proto__指向原型对象” 的表层认知#x…JavaScript 原型与继承终极指南从原理到实战2025 版原型与继承是 JavaScript 的核心灵魂也是前端面试的 “高频重灾区”。很多开发者深陷 “原型链迷宫”仅停留在 “__proto__指向原型对象” 的表层认知却不懂其底层设计逻辑与实战应用。本文从 “内存模型→核心概念→继承实现→框架应用→避坑指南” 五层逻辑结合 V8 引擎执行机制和 React/Vue 实战案例彻底拆解原型与继承的本质帮你真正掌握 JavaScript 的面向对象编程思想。一、底层原理为什么 JavaScript 没有 “类” 却能实现继承JavaScript 是一门 “基于原型的语言”而非传统面向对象的 “基于类的语言”。这一设计源于 Brendan EichJS 创始人的初衷 —— 在极短时间内设计一门兼具函数式和面向对象特性的语言原型机制正是折中后的最优解。1. 核心设计思想原型链继承本质通过 “原型对象”prototype实现属性和方法的共享通过 “原型链”__proto__串联实现属性的查找与继承。核心逻辑每个对象都有一个 “原型对象”当访问对象的属性 / 方法时若对象本身没有会通过__proto__向上查找原型对象直到找到或抵达原型链顶端Object.prototype.__proto__ null。2. V8 引擎视角的原型内存模型V8 引擎中原型相关的三个核心对象构成了继承的基础其内存关系如下Mermaid 流程图直观展示protoprototypeconstructorprotoproto属性name方法sayHello实例对象obj原型对象Foo.prototype构造函数FooObject.prototypenull张三console.log(Hello, ${this.name})protoprototypeconstructorprotoproto属性name方法sayHello实例对象obj原型对象Foo.prototype构造函数FooObject.prototypenull张三console.log(Hello, ${this.name})豆包你的 AI 助手助力每日工作学习关键关联实例对象的__proto__指向其构造函数的prototype原型对象原型对象的constructor指向其对应的构造函数所有原型对象最终继承自Object.prototype形成完整的原型链。3. 原型与构造函数的 “三角关系”必懂这是理解原型机制的核心三者相互关联、不可分割对象 / 函数核心属性 / 方法作用构造函数如 Fooprototype属性指向原型对象供实例继承属性 / 方法实例对象如 obj__proto__属性隐式原型指向构造函数的prototype开启原型链查找原型对象Foo.prototypeconstructor属性指向构造函数标识原型所属的构造函数验证代码浏览器控制台可直接执行javascript运行// 1. 定义构造函数 function Foo(name) { this.name name; // 实例属性每个实例独立 } // 2. 原型对象上定义共享方法 Foo.prototype.sayHello function() { console.log(Hello, ${this.name}); }; // 3. 创建实例 const obj new Foo(张三); // 验证三角关系 console.log(obj.__proto__ Foo.prototype); // true实例→原型对象 console.log(Foo.prototype.constructor Foo); // true原型对象→构造函数 console.log(obj.constructor Foo); // true实例通过原型链继承constructor二、核心概念彻底分清 prototype、__proto__与 constructor原型机制的混淆本质是对这三个核心概念的理解模糊。以下从 “定义、作用、使用场景” 三个维度彻底拆解1. prototype原型属性定义仅函数构造函数拥有的属性指向一个 “原型对象”。作用存储共享的属性和方法供其创建的所有实例继承避免每个实例重复创建相同方法节省内存。注意点普通对象没有prototype属性如const obj {}; obj.prototype → undefined箭头函数没有prototype属性无法作为构造函数使用。示例共享方法的实现核心用途javascript运行// 错误做法每个实例都创建独立方法浪费内存 function Bar(name) { this.name name; this.sayHi function() { // 实例方法每个实例一份 console.log(Hi, ${this.name}); }; } // 正确做法原型上定义共享方法所有实例共用一份 function Bar(name) { this.name name; } Bar.prototype.sayHi function() { // 原型方法所有实例共享 console.log(Hi, ${this.name}); }; const bar1 new Bar(李四); const bar2 new Bar(王五); console.log(bar1.sayHi bar2.sayHi); // true方法共享内存优化2.proto隐式原型定义所有对象包括函数都拥有的隐式属性ES6 标准化后可通过Object.getPrototypeOf()访问指向其 “原型对象”。作用构建原型链实现属性 / 方法的查找与继承。注意点不建议直接修改__proto__性能差易导致原型链混乱优先使用Object.create()指定原型__proto__是实例对象与原型对象的 “桥梁”而非构造函数的属性。示例原型链查找机制javascript运行// 原型链obj → Foo.prototype → Object.prototype → null const obj new Foo(张三); console.log(obj.name); // 张三实例本身拥有 console.log(obj.sayHello()); // Hello, 张三Foo.prototype拥有 console.log(obj.toString()); // [object Object]Object.prototype拥有 console.log(obj.nonExistent); // undefined原型链顶端仍未找到3. constructor构造函数指针定义原型对象上的属性指向其对应的构造函数。作用标识对象的 “创建者”可通过实例对象的constructor获取其构造函数。注意点若重写原型对象会覆盖constructor属性需手动修复否则指向错误实例对象的constructor是通过原型链继承自原型对象的。示例constructor 的修复场景javascript运行function Person(age) { this.age age; } // 重写原型对象覆盖默认constructor Person.prototype { run: function() { console.log(跑步年龄${this.age}); } }; const p new Person(25); console.log(p.constructor); // Object错误应为Person // 手动修复constructor Person.prototype.constructor Person; console.log(p.constructor); // Person正确三、JavaScript 的 6 种继承方式从基础到进阶JavaScript 没有原生的 “类继承” 语法ES6 的class本质是原型继承的语法糖但通过原型机制可实现多种继承方式不同方式各有优劣需根据场景选型。1. 原型链继承基础方式实现原理让子类的原型对象指向父类的实例通过原型链继承父类的属性和方法。实战代码javascript运行// 父类Animal function Animal(type) { this.type type; // 实例属性 this.eat function() { // 实例方法会被所有子类实例共享吗不 console.log(${this.type}在吃东西); }; } // 父类原型方法共享 Animal.prototype.sleep function() { console.log(${this.type}在睡觉); }; // 子类Dog继承Animal function Dog(name) { this.name name; } // 核心子类原型指向父类实例构建原型链 Dog.prototype new Animal(狗); // 修复constructor Dog.prototype.constructor Dog; // 子类添加自有方法 Dog.prototype.bark function() { console.log(${this.name}在叫); }; // 测试 const dog new Dog(旺财); dog.eat(); // 狗在吃东西继承自父类实例 dog.sleep(); // 狗在睡觉继承自父类原型 dog.bark(); // 旺财在叫子类自有方法 console.log(dog.__proto__ Dog.prototype); // true console.log(dog.__proto__.__proto__ Animal.prototype); // true原型链层级优点实现简单直接通过原型链继承父类所有属性和方法。缺点父类的实例属性会被所有子类实例共享如type属性修改一个实例会影响其他子类实例创建时无法向父类构造函数传递参数无法实现多继承。2. 构造函数继承解决实例属性共享问题实现原理在子类构造函数中通过call()/apply()调用父类构造函数将父类的实例属性绑定到子类实例上。实战代码javascript运行// 父类Animal function Animal(type) { this.type type; this.skills [跑, 跳]; // 引用类型实例属性 } // 子类Dog构造函数继承 function Dog(name, type) { // 核心调用父类构造函数绑定this为子类实例 Animal.call(this, type); this.name name; // 子类自有属性 } // 测试 const dog1 new Dog(旺财, 狗); const dog2 new Dog(来福, 狗); dog1.skills.push(叫); console.log(dog1.skills); // [跑, 跳, 叫] console.log(dog2.skills); // [跑, 跳]实例属性独立无共享问题 console.log(dog1.type); // 狗继承自父类 // 缺点无法继承父类原型上的方法 dog1.sleep(); // 报错dog1.sleep is not a function优点父类实例属性独立无共享问题子类实例创建时可向父类传递参数。缺点无法继承父类原型上的方法只能继承实例属性和方法父类的实例方法会被每个子类实例重复创建浪费内存。3. 组合继承原型链 构造函数最常用基础方式实现原理结合 “原型链继承” 和 “构造函数继承” 的优点 —— 原型链继承父类原型方法共享构造函数继承父类实例属性独立。实战代码javascript运行// 父类Animal function Animal(type) { this.type type; this.skills [跑, 跳]; } // 父类原型方法共享 Animal.prototype.sleep function() { console.log(${this.type}在睡觉); }; // 子类Dog组合继承 function Dog(name, type) { // 1. 构造函数继承继承实例属性独立 Animal.call(this, type); this.name name; } // 2. 原型链继承继承原型方法共享 Dog.prototype new Animal(); // 修复constructor Dog.prototype.constructor Dog; // 子类原型方法 Dog.prototype.bark function() { console.log(${this.name}在叫); }; // 测试 const dog1 new Dog(旺财, 狗); const dog2 new Dog(来福, 狗); // 实例属性独立 dog1.skills.push(叫); console.log(dog1.skills); // [跑, 跳, 叫] console.log(dog2.skills); // [跑, 跳] // 原型方法共享 console.log(dog1.sleep dog2.sleep); // true dog1.sleep(); // 狗在睡觉 // 子类方法正常 dog1.bark(); // 旺财在叫优点实例属性独立无共享问题原型方法共享节省内存支持向父类构造函数传递参数。缺点父类构造函数会被调用两次一次是new Animal()一次是Animal.call()子类原型上会存在父类的实例属性冗余如type、skills但会被子类实例属性覆盖。4. 寄生组合继承最优基础继承方式实现原理优化组合继承的缺点通过 “寄生构造函数” 创建父类原型的副本避免父类构造函数被调用两次。实战代码javascript运行// 父类Animal function Animal(type) { this.type type; this.skills [跑, 跳]; } Animal.prototype.sleep function() { console.log(${this.type}在睡觉); }; // 核心创建父类原型的副本不调用父类构造函数 function createProto(Parent) { function F() {} // 空构造函数寄生 F.prototype Parent.prototype; // 继承父类原型 return new F(); // 返回原型副本实例 } // 子类Dog寄生组合继承 function Dog(name, type) { Animal.call(this, type); // 构造函数继承仅调用一次父类构造 this.name name; } // 原型链继承子类原型指向父类原型副本 Dog.prototype createProto(Animal); // 修复constructor Dog.prototype.constructor Dog; // 子类方法 Dog.prototype.bark function() { console.log(${this.name}在叫); }; // 测试 const dog new Dog(旺财, 狗); console.log(dog.__proto__.__proto__ Animal.prototype); // true原型链正常 console.log(dog.type); // 狗实例属性正常 dog.sleep(); // 狗在睡觉原型方法正常优点组合继承的所有优点实例独立、原型共享、支持传参父类构造函数仅调用一次无冗余属性原型链清晰无多余层级。缺点实现稍复杂可封装为工具函数。5. ES6 class 继承语法糖推荐现代开发实现原理ES6 引入的class语法本质是原型继承的 “语法糖”底层逻辑与寄生组合继承一致但写法更简洁、直观。实战代码javascript运行// 父类Animalclass定义 class Animal { // 构造函数对应ES5的构造函数 constructor(type) { this.type type; this.skills [跑, 跳]; } // 原型方法对应ES5的Animal.prototype.method sleep() { console.log(${this.type}在睡觉); } // 静态方法不会被实例继承仅属于类本身 static eat() { console.log(动物都需要吃东西); } } // 子类Dogextends继承 class Dog extends Animal { constructor(name, type) { // 核心调用父类构造函数必须在this前调用 super(type); this.name name; // 子类自有属性 } // 子类原型方法 bark() { console.log(${this.name}在叫); } // 重写父类方法多态 sleep() { console.log(${this.name}${this.type}在打盹); } } // 测试 const dog new Dog(旺财, 狗); dog.bark(); // 旺财在叫子类方法 dog.sleep(); // 旺财狗在打盹重写父类方法 Animal.eat(); // 动物都需要吃东西静态方法类调用 console.log(dog instanceof Dog); // true console.log(dog instanceof Animal); // true继承关系成立优点语法简洁直观符合传统面向对象编程习惯原生支持继承、静态方法、方法重写多态底层逻辑优化无组合继承的缺点。缺点ES6 语法需兼容旧浏览器可通过 Babel 转译。6. 寄生继承补充方式实现原理基于现有对象创建新对象增强其属性和方法本质是 “原型继承 对象增强”。实战代码javascript运行// 父类Animal function Animal(type) { this.type type; } Animal.prototype.sleep function() { console.log(${this.type}在睡觉); }; // 寄生继承函数 function createDog(original, name) { // 创建父类实例的副本原型继承 const clone Object.create(original.prototype); // 增强对象添加自有属性和方法 clone.name name; clone.bark function() { console.log(${this.name}在叫); }; return clone; } // 测试 const dog createDog(Animal, 旺财); dog.type 狗; dog.sleep(); // 狗在睡觉继承父类原型方法 dog.bark(); // 旺财在叫增强方法优点实现简单可快速增强现有对象。缺点无法实现多继承增强的方法无法共享每个实例一份浪费内存。四、6 种继承方式对比选型表一目了然继承方式优点缺点适用场景原型链继承实现简单继承完整实例属性共享、无法传参、无多继承简单场景无需独立实例属性构造函数继承实例属性独立、支持传参无法继承原型方法、方法重复创建仅需继承父类实例属性的场景组合继承实例独立、原型共享、支持传参父类构造调用两次、原型有冗余属性ES5 环境的主流场景寄生组合继承实例独立、原型共享、支持传参、无冗余实现稍复杂ES5 环境的最优选择ES6 class 继承语法简洁、原生支持多态、无底层缺陷需 ES6 环境可转译现代开发React/Vue/Node.js寄生继承实现简单、可增强对象方法无法共享、无多继承快速增强现有对象的临时场景五、实战场景原型与继承的核心应用1. 框架中的原型应用React/Vue1Vue 组件的原型链Vue 组件实例的原型链为VueComponent实例 → VueComponent.prototype → Vue.prototype因此可通过Vue.prototype挂载全局方法 / 属性javascript运行// 全局挂载工具方法通过原型链共享 Vue.prototype.$formatDate function(date) { return date.toLocaleDateString(zh-CN); }; // 所有组件实例均可访问 new Vue({ mounted() { console.log(this.$formatDate(new Date())); // 所有组件共享该方法 } });2React 类组件的继承React 类组件基于 ES6class继承Component类的原型方法如setState、componentDidMount被所有子类组件继承javascript运行// 子类组件继承React.Component class App extends React.Component { constructor(props) { super(props); // 调用父类构造函数 this.state { count: 0 }; } render() { return ( div p计数{this.state.count}/p button onClick{() this.setState({ count: this.state.count 1 })} 加1 /button /div ); } }2. 原型链排错实战问题实例属性被意外覆盖javascript运行// 父类 function Person() { this.hobbies [读书]; } // 子类 function Student() {} Student.prototype new Person(); const s1 new Student(); const s2 new Student(); s1.hobbies.push(运动); console.log(s2.hobbies); // [读书, 运动]意外共享原因父类实例属性被子类实例共享原型链继承的缺陷解决方案改用组合继承或 ES6 class 继承通过call()绑定实例属性3. 手动实现new关键字原型核心面试题new关键字的本质是创建实例对象并关联原型链手动实现可深度理解原型机制javascript运行function myNew(constructor, ...args) { // 1. 创建空对象 const obj {}; // 2. 关联原型链obj.__proto__ constructor.prototype Object.setPrototypeOf(obj, constructor.prototype); // 3. 调用构造函数绑定this为obj const result constructor.apply(obj, args); // 4. 若构造函数返回对象返回该对象否则返回obj return typeof result object result ! null ? result : obj; } // 测试 function Foo(name) { this.name name; } Foo.prototype.sayHello function() { console.log(Hello, ${this.name}); }; const obj myNew(Foo, 张三); obj.sayHello(); // Hello, 张三原型链关联成功六、避坑指南90% 开发者踩过的 5 个坑1. 坑点 1重写原型后未修复constructor问题代码javascript运行function Person() {} Person.prototype { run: function() {} }; const p new Person(); console.log(p.constructor Person); // false指向Object原因重写原型对象时覆盖了默认的constructor属性。解决方案手动修复constructor指向javascript运行Person.prototype.constructor Person;2. 坑点 2混淆 “原型链查找优先级”问题代码javascript运行function Foo() { this.name 实例属性; } Foo.prototype.name 原型属性; const obj new Foo(); console.log(obj.name); // 实例属性预期原型属性原因实例属性优先级高于原型属性查找时先找实例再找原型。解决方案若需访问原型属性需通过Object.getPrototypeOf(obj).name。3. 坑点 3直接修改__proto__导致性能问题问题__proto__是访问器属性直接修改会触发原型链重构性能极差。解决方案创建对象时通过Object.create()指定原型javascript运行const proto { name: 张三 }; const obj Object.create(proto); // 替代 obj.__proto__ proto4. 坑点 4认为 “ES6 class 是真正的类继承”问题误以为class是 JavaScript 新增的 “类继承” 机制忽略其原型本质。真相class是原型继承的语法糖底层仍依赖prototype和__proto__。验证javascript运行class Foo {} console.log(Foo.prototype); // 存在原型对象证明其原型本质5. 坑点 5原型上定义引用类型属性问题代码javascript运行function Foo() {} Foo.prototype.list []; const obj1 new Foo(); const obj2 new Foo(); obj1.list.push(1); console.log(obj2.list); // [1]意外共享原因原型上的引用类型属性会被所有实例共享。解决方案将引用类型属性定义在构造函数中实例属性javascript运行function Foo() { this.list []; // 每个实例独立拥有 }七、总结核心知识点速查表与原则1. 核心知识点速查表核心概念关键结论原型链实例→构造函数.prototype→父类.prototype→Object.prototype→null继承方式选型现代开发优先 ES6 classES5 环境用寄生组合继承查找优先级实例属性 原型属性 父类原型属性核心属性关系实例.proto 构造函数.prototype静态方法属于类本身不被实例继承ES6 class 用 static 关键字2. 核心原则记住 3 句话原型用于共享方法和不变属性定义在原型上节省内存实例用于独立引用类型属性和可变属性定义在实例上避免共享现代优先 ES6 class语法简洁、无底层缺陷是当前开发的最优选择。八、拓展学习资源MDN 官方文档原型链与继承V8 引擎官方博客《JavaScript 原型机制解析》面试高频题《手动实现 ES6 class 继承》《原型链查找的实现原理》原型与继承的核心是理解 “共享与独立” 的设计思想 —— 原型负责共享方法实例负责存储独立属性。掌握这一思想再结合实战场景反复练习就能彻底走出 “原型链迷宫”写出更高效、易维护的 JavaScript 代码。
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

阿里云做网站官网蓝色风格企业网站

Windows Shell脚本编程基础指南 1. Windows命令控制台交互脚本 在Windows命令控制台中,我们可以通过编写脚本来实现不同的功能,并且可以根据变量的值来改变控制台的外观和显示信息。 首先,我们定义了一个变量 TestVariable ,它的值是随机生成的。根据这个变量的值,脚…

张小明 2026/1/6 15:49:11 网站建设

国家精品课程网官网手机管家一键优化

尚存在的问题及采取的措施:一、项目进展概述截至目前,线上零食销售系统的设计与实现工作已进展至中期阶段。系统整体架构已搭建完成,并成功划分了前台模块与后台管理模块。前台模块实现了物品类别的查询、物品信息的查看、物品的订购、购物车功能以及个人…

张小明 2026/1/9 2:35:10 网站建设

西安网站制作怎么选wordpress模板

Wan2.2-T2V-5B模型部署指南:基于OpenSpec的容器化方案 在短视频内容需求呈指数级增长的今天,从一条广告语生成一段动态视频,已不再是影视工作室的专属能力。越来越多的企业希望将文本到视频(Text-to-Video, T2V)技术集…

张小明 2026/1/8 13:44:19 网站建设

nodejs做网站还是app个人社保缴费应交多少

在当今数字化时代,数据安全和隐私保护变得尤为重要。Hyperbeam作为一个基于Hyperswarm和Noise协议的1对1端到端加密网络通道,为开发者提供了一种简单而强大的解决方案。本文将深入探讨Hyperbeam的核心特性、使用方法以及实际应用场景。 【免费下载链接】…

张小明 2026/1/8 5:42:31 网站建设

网站建设公司推广方案荣耀手机正品官网查询

手把手教你用Keil5烧录C语言程序:从零开始搞定STM32开发全流程 你是不是也遇到过这种情况——代码写好了,编译通过了,结果一点击“Download”,Keil弹出一句冷冰冰的提示:“ No target connected ”?或者更…

张小明 2026/1/9 8:18:17 网站建设

深圳做网站的公司 cheungdom网站平台推广

高效管理Vim多文件:实用缓冲区配置指南 【免费下载链接】vim-airline 项目地址: https://gitcode.com/gh_mirrors/vim/vim-airline 你是否曾在Vim中同时编辑多个文件时感到手忙脚乱?当打开十几个文件后,传统的:bn和:bp切换方式让人头…

张小明 2026/1/7 20:12:27 网站建设