一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

JavaScript 原型链机制下的属性动态发现与绑定过程

时间:2026-07-11 11:11:52 编辑:袖梨 来源:一聚教程网

JavaScript属性访问是运行时按需查找+懒绑定,先查实例自有属性,再沿原型链逐层向上直至null;写入默认作用于实例自身,不修改原型;可枚举性与访问性相互独立。

JavaScript 中属性的动态发现与绑定,本质上是运行时按需查找 + 懒绑定的过程,不预先声明、不静态编译,全靠原型链实时导航。

属性查找:从实例到 null 的逐层试探

当你访问 obj.prop 时,引擎不会提前知道这个属性在哪。它严格按以下顺序行动:

  • 先检查 obj 自身是否拥有该属性(自有属性,即 Object.hasOwnProperty('prop') 为 true)
  • 如果没有,立即读取 obj.__proto__(即 Object.getPrototypeOf(obj)),在该对象上查找
  • 若仍无,继续读取该原型的 __proto__,重复查找
  • 直到某一层找到该属性,或抵达 Object.prototype.__proto__ === null 终止,返回 undefined

这个过程完全动态,每次访问都走一遍链——不是缓存路径,而是实时“导航”。即使你在运行中修改了某层原型(比如给 Array.prototype 新增方法),后续所有数组实例立刻能访问到,因为查找逻辑始终生效。

绑定不发生:只有访问,没有“绑定”这回事

JavaScript 中并不存在传统意义上的“属性绑定”。所谓“调用 obj.method()”,其实只是:

立即学习“Java免费学习笔记(深入)”;

  • 查找到 method 函数(可能在原型上)
  • obj 作为 this 上下文执行它

函数本身并不“属于” obj;它只是被查找到、被调用。你可以把同一个函数赋给多个对象,也可以临时替换某个实例的属性覆盖原型上的同名方法——所有这些操作都不影响原型链结构,只改变某次查找的结果。

写入属性:默认写在实例自身,不自动修改原型

当你执行 obj.prop = value,引擎默认在 obj 自身上创建或更新属性,不会顺着原型链向上写。这是关键设计:

  • 即使 obj 的原型上有同名 prop,赋值也只作用于 obj 自身(屏蔽效应)
  • 想真正修改原型上的共享属性,必须显式操作,如 Constructor.prototype.prop = value
  • 这也是为什么给数组加 last 方法要写 Array.prototype.last = function(){...},而不是 [].last = ...

可枚举性与属性描述符影响可见性

属性能否被 for...inObject.keys() 看到,取决于它的 enumerable 描述符,而非位置。例如:

  • Object.prototype.toString 存在于原型链上,但 enumerable: false,所以遍历时不可见
  • 你用 Object.defineProperty 在原型上添加非枚举属性,它依然能被点号访问,但不会出现在循环中

也就是说,“能访问”和“能枚举”是两套机制——查找走原型链,遍历看描述符。

热门栏目