资讯动态

JavaScript 原型链是什么?new 和继承是怎么实现的?

发布时间:2026/10/14 11:33:10 来源:尧图企业网站定制
JavaScript 原型链是什么new 和继承是怎么实现的原型链就是 JavaScript 查找对象属性的一条路径。先查对象自己的属性没有找到再查它的原型继续往上找直到原型为 null。用 new 创建实例时实例通常会连接到构造函数的 prototype 对象。因此多个实例可以共用原型上的方法不需要各保存一份。但共享不代表所有数据都应该放在原型上。姓名、当前选择等属于某个实例的数据应当保存在实例自己身上。如果把可变数组放在原型上几个实例可能读到同一个数组修改时就会相互影响。实际写代码时可以用 Object.getPrototypeOf 看原型用 Object.hasOwn 判断属性是不是对象自己的。读属性、给属性赋值、修改属性指向的对象也需要分开分析。顺着一次属性读取把对象关系看清楚先看一个对象为什么能使用自己没有的方法假设咱们正在做一个用户管理页面。每个用户对象保存自己的 name但显示姓名的方法没有必要给每个人复制一份。可以把这个方法放在一个共享对象里再让每个用户对象把它作为原型。读取 user.showName 时JavaScript 先检查 user。如果 user 自己没有 showName就继续检查它的原型。找到方法以后调用 user.showName()普通方法里的 this 仍然指向 user。查到方法的位置和调用时的接收对象是两件事。因此原型链并不是把父对象的属性全部复制到子对象。它保存的是对象之间的查找关系。构造函数的 prototype 和实例的原型分别是什么User 是可以被调用的构造函数User.prototype 是一个普通对象。通常new User() 得到的实例其内部原型指向 User.prototype。构造函数自己也是对象因此 User 自己还有另一条原型关系。不能看见名字里都有 prototype就把两条关系混在一起。下面代码用 TypeScript 表达 JavaScript 的对象机制。Python 使用自己的类与属性查找模型没有与这段代码同义的 prototype API所以这里不补一个看起来相似的版本。constshared{role:reader};constuserObject.create(shared)as{role:string};console.log(user.role);// readerconsole.log(Object.hasOwn(user,role));// falseuser.roleeditor;console.log(shared.role);// readerconsole.log(Object.hasOwn(user,role));// true前一次读取沿原型取得 reader。后一次赋值在本例中给 user 新增自己的 role遮住了原型上的同名属性并没有改写 shared.role。访问器、只读属性等情况还要按对应规则分析。new 不只是把 prototype 接上去对于普通可构造函数可以按四个动作理解创建新对象让它连接到构造函数的 prototype把它作为 this 执行构造函数最后决定返回哪个对象。通常返回新实例。但如果构造函数明确返回另一个对象new 的结果可以是那个对象。返回普通原始值时通常仍使用新实例。这也解释了为什么手写 new 不能只写 Object.create。初始化代码还没有执行返回值规则也没有处理。类、内建构造函数以及特殊构造行为更复杂教学版模拟不能宣称替代语言实现。共享数组为什么会让实例互相影响如果原型上保存 items []两个实例读取 items 时都可能拿到同一个数组。执行 userA.items.push(“book”)修改的是那个数组userB 当然也能看到。但执行 userA.items []是在本例中给 A 保存另一个数组B 的读取路径没有改变。一个动作修改共享对象另一个动作改变当前对象上的属性结果不同。可以用一个很小的实验确认先比较两个实例的 items 是否严格相等再分别做 push 和重新赋值。把引用关系画清楚比背“原型用于继承”更容易接住追问。本题机制参考MDN 原型链。面试官继续追问删除实例自己的同名属性以后会怎样如果删除成功后续读取会重新沿原型查找。所以删除 user.role不等于任何地方都没有 role。Object.create(null) 适合什么情况它没有通常的 Object.prototype可以用来创建没有继承属性的字典。但也没有常见的实例方法需要用 Object.hasOwn 等静态方法检查多数普通键值场景也可以考虑 Map。为什么不建议随便修改内建原型新增方法可能与其他库、未来标准或枚举行为发生冲突。业务复用优先使用自己的类、组合对象或函数不把全局原型当项目工具箱。面试速记卡查找自身属性优先再沿原型找直到 null。对象关系实例的原型通常是构造函数的 prototype。共享原型方法可以复用实例可变数据要谨慎放置。修改重新赋值与修改共享对象内部是不同动作。验证Object.getPrototypeOf 看关系Object.hasOwn 看归属。我是程序员Sunday。本文收录于 sunday面试指南原文与配图可继续阅读。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑