javascript动态属性机制的核心在于对象是运行时可变的属性集合,赋值操作(如obj.x=1)始终写入对象自身,读取时才沿原型链查找;three.js中vector3实例可自由添加rotationaxis等自定义属性,因其本质是普通js对象。

对象自身属性 vs 原型链上的属性
当你写 obj.name = "Alice",JS 引擎始终先在 obj 自身 上创建或修改 name 属性,完全不检查原型上有没有同名属性。原型链只在 读取时才参与查找(即“就近原则”:先找自身,找不到再沿 __proto__ 向上找)。这意味着:
- 动态添加的属性默认属于对象自身,
obj.hasOwnProperty("name")返回true -
delete obj.name只影响自身属性,不影响原型上同名属性 - 哪怕
Object.prototype上有toString,你仍可给某个 obj 单独设置obj.toString = () => "custom",覆盖继承行为
三种赋值方式的实际差异
点号、方括号、计算属性名,表面是语法不同,底层都是向对象自身写入键值对,但适用场景明确:
-
点号(
obj.x):仅限静态、合法标识符(如userAge),不能用变量或含连字符的名 -
方括号(
obj[key]):key 是表达式,支持变量、字符串拼接、甚至Symbol,是运行时确定键名的通用方案 -
计算属性名(
{[key]: value}):专用于对象字面量初始化阶段,让创建和赋值一步到位
为什么 Three.js 的 Vector3 能挂 rotationAxis?
THREE.Vector3 实例本质上就是普通 JS 对象,它的 x/y/z 是自身属性,但引擎不限制你额外加 rotationAxis 或 metadata。这不是“扩展类”,而是直接往实例上写:
- 每个顶点
vertex都是独立对象,vertex.rotationAxis = new THREE.Vector3(0,1,0)就是新增一个自身属性 - 后续代码通过
vertex.rotationAxis访问,走的是自身属性路径,不依赖原型或 Three.js 源码 - 这种做法轻量、无需修改库源码,特别适合临时绑定渲染逻辑所需的状态数据
动态性不是随意性,需注意边界
动态添加本身无性能问题,但需清醒认知其行为边界:
-
for...in会遍历自身 + 可枚举的原型属性;要用Object.keys()或Object.getOwnPropertyNames()限定范围 - 用
Object.defineProperty添加的属性,默认enumerable: false,不会出现在for...in或JSON.stringify中 - 箭头函数没有自己的
this和arguments,但动态属性不受影响——它只关乎对象本身,与函数类型无关
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











