JavaScript中检测全局函数是否存在的最优方法是什么
JavaScript检测全局函数是否存在的方案对比与最优选择
现有两种方案的优劣分析
typeof 方案
if(typeof window.myFunc != 'function'){ window.myFunc = function(){ // payload } }
- 优势:是通用性、稳妥性最高的方案,
typeof操作符访问未声明的变量也不会抛出ReferenceError,同时能精准校验值的类型是否为函数,不会把同名的字符串、数字、普通对象等非函数值误判为有效函数,避免后续调用时报类型错误。性能属于第一梯队,typeof是JS底层原生操作,耗时为纳秒级,日常场景完全感知不到性能损耗。 - 劣势:写法相对繁琐,需要多行代码完成判断+赋值逻辑。
短路赋值方案
注意你给出的短路赋值代码存在语法错误:应该用赋值运算符=而非相等运算符==,否则只会做判断不会完成赋值,正确写法如下:
window.myFunc = window.myFunc || function(){ // payload }
- 优势:写法简洁,一行即可完成存在判断+赋值的逻辑,符合短路语法的书写习惯。
- 劣势:容错性极低,风险较高:如果已存在的
window.myFunc是0、空字符串、null、false这类假值,会直接被新函数覆盖;同时如果存在的window.myFunc是普通对象、字符串等非函数真值,会被直接保留,后续调用时会抛出is not a function的错误。性能上和typeof方案几乎一致,但稳定性差很多。
最优方案选择
从性能维度看,上述两种方案耗时几乎没有差异,都是当前最快的实现方式,日常开发中优先选稳妥性更高的typeof方案,性能完全达标,同时能避免90%以上的边界case问题。
其他可选方案
1. hasOwnProperty 结合 typeof 方案
if (!window.hasOwnProperty('myFunc') || typeof window.myFunc !== 'function') { window.myFunc = function() { /* payload */ } }
适用场景:需要严格区分自定义全局函数和Window原型链上继承的原生属性时使用,避免把浏览器内置的同名方法误判为自定义的已实现函数。
2. 可选链结合 typeof 方案(ES2020+支持)
if (typeof window?.myFunc !== 'function') { window.myFunc = () => { /* payload */ } }
适用场景:多端适配的代码场景(比如要同时兼容浏览器、Node、小程序等不存在window对象的环境),可选链语法避免访问不存在的window对象时抛出错误。
适用场景总结
- 个人demo、内部小工具,能确保全局不会出现同名非函数值的场景,可以用短路赋值方案,写法更高效。
- 生产环境业务代码、公共SDK开发,优先选择typeof方案,稳定性最高。
- 要严格区分自定义全局属性和原生继承属性的场景,加
hasOwnProperty判断即可。 - 跨端适配代码,用可选链+typeof的组合方案。
内容的提问来源于stack exchange,提问作者Sean Dillon
相关产品推荐
相关产品推荐

