单元测试中校验原型链应使用Object.getPrototypeOf()逐级断言,避免__proto__;用isPrototypeOf()验证间接继承;instanceof仅适用于同上下文构造函数检测;可封装工具函数提升可读性与健壮性。

在单元测试中校验原型链,核心是避免依赖非标准的 __proto__,改用规范、可预测的 API 逐级断言,同时覆盖常见边界(如内置类型、自定义类、跨原型链继承)。
用 Object.getPrototypeOf() 逐级断言原型指向
这是最可靠的方式。每个对象的显式原型必须通过 Object.getPrototypeOf() 获取,再与预期原型严格比对(===)。
- 不要写
obj.__proto__ === Array.prototype——__proto__已废弃,且在某些环境(如 strict 模式或旧 IE)可能不可写/不可访问 - 正确写法:
assert(Object.getPrototypeOf(arr) === Array.prototype, 'arr 的直接原型是 Array.prototype') - 验证完整链:对
Array.prototype继续查:assert(Object.getPrototypeOf(Array.prototype) === Object.prototype, 'Array.prototype 的原型是 Object.prototype') - 终点必须为
null:assert(Object.getPrototypeOf(Object.prototype) === null, 'Object.prototype 的原型为 null')
用 isPrototypeOf() 断言某对象是否在目标对象的原型链上
适合验证「间接继承关系」,比如判断 Object.prototype 是否参与了某个实例的原型查找路径。
- 语法:
expectedProto.isPrototypeOf(targetObj),返回布尔值 - 例:
assert(Object.prototype.isPrototypeOf([1,2]), '数组继承自 Object.prototype') - 注意左边必须是对象(不能是字面量
{}),否则会报TypeError;推荐固定用Object.prototype、Array.prototype等已知原型对象 - 不适用于判断「直接原型」,只反映「是否存在于整条链中」
用 instanceof 辅助验证构造器归属,但需警惕局限性
它底层依赖原型链查找,适合测试「是否由某构造函数创建」这一语义,但不是纯原型指针断言。
立即学习“Java免费学习笔记(深入)”;
- 例:
assert(obj instanceof Date, 'obj 是 Date 实例')→ 等价于检查obj.__proto__链中是否存在Date.prototype - 慎用于字面量:
42 instanceof Number为false(数字字面量不是Number实例),应改用Object.prototype.toString.call(42) === '[object Number]' - 跨 iframe 时失效——不同上下文的
Array构造函数不共享prototype,此时instanceof返回false,应改用Object.getPrototypeOf()+isPrototypeOf()组合断言
封装可复用的原型链断言工具函数
避免重复写多层 Object.getPrototypeOf 调用,提高测试可读性与健壮性。
- 验证单层:
function assertPrototypeIs(obj, expectedProto, msg) { assert(Object.getPrototypeOf(obj) === expectedProto, msg); } - 验证整条链是否以指定原型结尾:
function assertPrototypeChainEndsAt(obj, endProto) { let p = obj; while (p !== null && p !== endProto) p = Object.getPrototypeOf(p); assert(p === endProto, `原型链最终未到达 ${endProto.constructor?.name || 'unknown'}`); } - 验证是否包含某原型(等价于
isPrototypeOf封装):function assertInPrototypeChain(prototype, obj, msg) { assert(prototype.isPrototypeOf(obj), msg); }


















