javascript中对象的“来源”由原型链结构决定,应使用object.getprototypeof()逐级追踪[[prototype]]指针直至null,而非依赖可被篡改的constructor属性或__proto__。

JavaScript 中对象的“来源”不是指创建它的代码位置,而是指它的原型链结构——即它继承自哪个构造函数、是否是某个类的实例、有没有被 Object.create 或 Object.setPrototypeOf 修改过原型。追踪原型链的核心是理解 __proto__(非标准但广泛支持)、Object.getPrototypeOf() 和 constructor 的关系,并避免误把构造函数名当作唯一标识。
用 Object.getPrototypeOf 逐级查看原型
这是最可靠、符合标准的方式。每个对象都有一个内部 [[Prototype]] 指针,Object.getPrototypeOf(obj) 可安全读取它:
- 对普通对象:
Object.getPrototypeOf({}) === Object.prototype - 对数组:
Object.getPrototypeOf([1,2]) === Array.prototype - 对自定义类实例:
Object.getPrototypeOf(new MyClass()) === MyClass.prototype
你可以循环调用它直到返回 null,就走到了原型链顶端:
function traceProto(obj) {
let current = obj;
while (current !== null) {
console.log(current.constructor?.name || 'null');
current = Object.getPrototypeOf(current);
}
}
traceProto([1, 2]); // Array → Object → null
区分 constructor 属性和真实构造逻辑
obj.constructor 只是一个属性,可被修改,不能单独作为“来源”依据:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 如果没动过原型,
obj.constructor通常指向创建它的构造函数 - 但一旦执行
obj.__proto__ = Foo.prototype或Object.setPrototypeOf(obj, Foo.prototype),constructor可能仍指向旧构造函数(因为Foo.prototype.constructor没同步改) - 建议优先查
Object.getPrototypeOf(obj).constructor,而非obj.constructor
识别内置类型与自定义类型
不要只依赖 constructor.name 判断类型,有些对象没有明确构造函数(如 Object.create(null) 创建的):
- 用
Object.prototype.toString.call(obj)获取规范类型标签,例如[object Array]、[object Date] - 对自定义类,检查
obj instanceof MyClass更语义清晰,它本质就是沿原型链查找MyClass.prototype - 注意:
instanceof在跨 iframe 场景会失效(因不同全局环境的 Array 构造函数不等价),此时需用Array.isArray()等专用方法
警惕原型链被手动篡改的情况
开发中常见人为干预原型链的操作,会使“来源”变得模糊:
-
Object.setPrototypeOf(obj, null):切断继承,obj不再继承任何东西 -
Object.setPrototypeOf(obj, {}):让对象直接继承空对象,丢失toString等基础方法 - 给
prototype赋值时未重设constructor,导致obj.constructor指向错误
若怀疑原型被改过,先用 Object.getPrototypeOf(obj) 查当前原型,再比对预期值,比猜 constructor 更直接。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










