JavaScript函数赋值后调用getElementById报Illegal invocation的原因
异常核心成因:JavaScript 函数的
this 绑定规则 你遇到的报错和页面中是否存在 id 为 main 的元素完全无关,核心是浏览器原生方法对调用上下文有强制要求:
- 从对象上取出的方法,本质只是函数本身的内存引用,不会自动携带它原本所属的宿主对象一起完成赋值。
- JavaScript 中函数的
this值完全由调用方式决定,而非函数定义时的位置:- 以
对象.方法()的语法调用时,this会自动绑定到前面的对象; - 把方法单独赋值给变量,再以
变量()的形式直接调用时,非严格模式下this会指向全局对象,严格模式下this为undefined,完全和方法原本的宿主对象脱节。
- 以
为什么同样的写法在 JSON.stringify 上不会报错?
JSON.stringify的内部实现没有对this值做校验,哪怕调用时this指向全局对象,序列化逻辑也能正常执行,因此会给人一种「直接赋值方法引用是通用操作」的错觉。
而document.getElementById是浏览器实现的原生 DOM 方法,它的内部逻辑强要求调用时this必须指向document对象本身。当你单独把方法引用抽出来当普通函数调用时,浏览器检测到this不符合预期,就会抛出Uncaught TypeError: Illegal invocation(非法调用)的错误。
正确的使用方式
如果要把这类依赖上下文的原生方法单独抽离使用,必须手动把方法的this绑定回原本的宿主对象:
// 用bind永久绑定方法的上下文 const doc = document.getElementById.bind(document) doc('main') // 可正常返回目标DOM元素 // 也可以在调用时临时指定this指向 const doc = document.getElementById doc.call(document, 'main') // 同样可以正常执行
内容的提问来源于stack exchange,提问作者KienHT
相关产品推荐
相关产品推荐

