JS 原型链,一篇文章让你彻底记住(忘都忘不掉)
JS 原型链一篇文章让你彻底记住忘都忘不掉1. 问题背景真实场景你一定遇到过这些情况functionPerson(name){this.namename;}Person.prototype.sayHifunction(){console.log(Hi, this.name);};constpnewPerson(Tom);p.sayHi();// OK 但问题来了console.log(p.__proto__Person.prototype);// trueconsole.log(Person.prototype.__proto__Object.prototype);// true❗ 很多人到这里就懵了__proto__是啥为什么一层一层能找到方法到底是谁在“帮我找 sayHi”2. 核心问题本质分析JS 原型链的本质就一句话❗ 对象在访问属性时如果自己没有就会沿着“原型链”向上查找3. 原理讲解彻底讲透3.1 JS 中其实只有对象constobj{};constarr[];constfnfunction(){}; 本质上对象 ✔数组 ✔对象的一种函数 ✔对象的一种3.2 每个对象都有一个隐藏属性 叫做[[Prototype]]在代码中通常用obj.__proto__3.3 原型链长什么样functionPerson(){}constpnewPerson(); 内部结构是p ↓ __proto__ Person.prototype ↓ __proto__ Object.prototype ↓ __proto__ null 这条链就叫 原型链Prototype Chain3.4 属性查找过程重点p.sayHi(); JS 做了什么在p自身找没有 →去p.__proto__Person.prototype找还没有 →去Object.prototype再没有 →返回undefined 用一句话记住❗ JS 查属性 “就近原则 一路向上找”4. 常见错误 / 误区❌ 误区 1prototype 是所有对象都有的错constobj{};console.log(obj.prototype);// undefined 只有函数才有functionA(){}console.log(A.prototype);// ✔❌ 误区 2proto和 prototype 是一个东西❗ 完全不是名称属于谁作用prototype函数用来创建实例的原型__proto__所有对象指向其原型 关系是p.__proto__Person.prototype❌ 误区 3修改 prototype 不会影响实例Person.prototype.sayHifunction(){}; 所有实例都会受影响❗ 因为它们“共享同一个原型对象”5. 解决方案分层理解第一层使用层 会用arr.push()obj.toString()第二层理解层 知道来源arr.__proto__Array.prototype第三层掌控层 能自己设计原型functionAnimal(name){this.namename;}Animal.prototype.eatfunction(){console.log(this.name eating);};第四层架构层 控制继承关系functionDog(name){Animal.call(this,name);}Dog.prototypeObject.create(Animal.prototype);Dog.prototype.constructorDog;6. 工程实现真实项目写法 一个典型继承封装functioninherit(sub,sup){sub.prototypeObject.create(sup.prototype);sub.prototype.constructorsub;}使用functionAnimal(name){this.namename;}Animal.prototype.eatfunction(){console.log(eat);};functionDog(name){Animal.call(this,name);}inherit(Dog,Animal);Dog.prototype.barkfunction(){console.log(bark);}; 这就是很多框架底层干的事包括 Vue27. 架构 / 设计思路 为什么 JS 要设计原型链不是为了炫技而是✔ 1. 节省内存functionPerson(){this.sayHifunction(){};}❌ 每个实例一份浪费Person.prototype.sayHifunction(){};✔ 所有实例共享✔ 2. 动态扩展能力Person.prototype.runfunction(){}; 已经创建的实例也能用✔ 3. 支持“委托模型” JS 不是传统继承而是❗ 对象 → 委托给原型对象8. 性能 / 优化建议❗ 不要频繁改 prototypePerson.prototype{} 会破坏原有链影响性能 可读性✔ 优先用 class语法糖classPerson{constructor(name){this.namename;}sayHi(){console.log(this.name);}} 本质还是原型链9. 总结认知提升 你要记住这 3 句话❗ JS 一切皆对象函数也是❗ 对象查属性会沿原型链向上找❗ 原型链的本质是“对象之间的委托关系” 一句话终极理解原型链 对象找不到属性时的“兜底查找机制”10. 延伸思考 想真正吃透原型链你必须继续思考new到底做了什么this和原型链有什么关系call / apply / bind为什么能改变 thisclass 为什么只是语法糖 如果你现在能回答p.sayHi()到底经历了什么查找过程那说明你已经真的懂了。完结撒花✿✿ヽ(°▽°)ノ✿
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2441885.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!