new.target 是 JavaScript 中用于检测函数是否通过 new 调用的元属性,构造调用时指向当前构造函数,否则为 undefined;它不可伪造、仅在 new 表达式中有效,是拦截非法实例化的第一道守门员,适用于限制调用方式、实现抽象基类及配合 Proxy 构造拦截。

new.target 本身不直接防范微任务实例化,但它能精准识别构造调用上下文,是拦截非法类实例化的第一道守门员。关键在于:它只在 new 表达式中有效,且在普通函数调用、Reflect.construct 或箭头函数中为 undefined——这个不可伪造的特性,正好用来区分“合法初始化”和“插件偷偷 new 出来的伪装实例”。
一、用 new.target 拦截非预期的 new 调用
很多第三方插件会尝试用 new CustomEvent()、new Promise() 或自定义类(如 new MutationObserver())注入逻辑。你可以在自己的封装类或代理构造器中检查 new.target 是否匹配预期:
- 若
new.target !== MySafeClass,说明有人绕过你的 API 直接 new,可立即 throw 错误或返回空对象 - 对原生类无法修改,但可代理其构造器:
const SafePromise = new Proxy(Promise, { construct(target, args, newTarget) { if (newTarget === Promise) throw new Error('禁止直接 new Promise'); return Reflect.construct(target, args, newTarget); } }) - 注意:此方式仅对显式
new生效,不拦截插件内部通过eval、Function构造或setTimeout(() => {}, 0)等间接触发的微任务
二、结合微任务队列特征做二次校验
单纯靠 new.target 不够,因为插件可能用 queueMicrotask 或 Promise.resolve().then() 绕过构造检测。此时需在微任务执行前加一层上下文快照:
- 在应用启动时记录当前微任务队列状态(如
performance.now()+ 栈深度标记) - 在关键回调入口(如
then回调、queueMicrotask参数函数)里检查调用栈是否含已知插件域名或可疑函数名 - 用
Error.captureStackTrace(V8)或new Error().stack提取调用链,过滤掉chrome-extension://或moz-extension://开头的帧
三、冻结关键原型并监控 new 行为
插件常通过污染 Promise.prototype 或 EventTarget.prototype 来劫持后续实例行为。防御重点不是阻止 new,而是确保 new 出来的对象“干净”:
- 启动时用
Object.freeze(Promise.prototype)和Object.seal(Promise),防止方法被覆盖或新增属性 - 对敏感构造器(如
MutationObserver、IntersectionObserver)做Object.getPrototypeOf快照,运行中定期比对是否被替换 - 配合
Proxy劫持Promise的then和catch,在回调执行前验证this是否为原始构造器产出的实例(用Object.getPrototypeOf(this) === Promise.prototype)
四、限制扩展权限并隔离执行环境
很多恶意实例化源自浏览器扩展的注入脚本。从源头降低风险更有效:
- 在
Content-Security-Policy中禁用unsafe-eval和unsafe-inline,阻断动态代码执行路径 - 使用
iframe sandbox="allow-scripts"加载第三方内容,隔离其对主页面原型链的访问能力 - 对已知高危扩展(如假冒 TronLink)的 ID 列表,在页面加载时通过
chrome.runtime.sendMessage(需 manifest 权限)探测其是否存在,存在则禁用敏感 API

















