如何在JavaScript中访问定义在另一函数、IF语句内部的变量值
JavaScript变量访问undefined问题排查与解决
问题描述
我在JavaScript开发过程中遇到变量访问异常问题:变量totalActivatedOffers定义在IF判断语句内部的函数中,需要在IF语句外的其他位置调用该变量的值,但运行时始终返回undefined,无法正常获取。
我已经在脚本块顶部提前声明了该变量,声明代码如下:
var totalActivatedOffers;
但上述操作仍未解决问题,变量赋值的简化示例代码如下:
if ("SSO" in sessionStorage) { setTimeout(function(){ if (firstArrayLength.length == 3) { var totalActivatedSparksOffers = 4; } if (secondArrayLength.length == 3) { var totalActivatedRewardsOffers = 7; } var totalActivatedOffers = totalActivatedSparksOffers + totalActivatedRewardsOffers; }, 2500) } // 关闭判断sessionStorage是否存在SSO的逻辑 // 需要在IF语句外的此处访问变量值 console.log('Total activated offers to subtract is ' + totalActivatedOffers);
问题原因
- 异步时序问题:
setTimeout是异步API,传入的回调函数会在同步代码执行完成、且延迟2500毫秒后才会执行。而示例中console.log是同步代码,会在回调执行前就运行,此时变量还未被赋值,自然返回undefined。 - 变量作用域覆盖问题:你在
setTimeout回调内部又使用var声明了一次totalActivatedOffers,由于var的函数作用域特性,这里会创建一个回调函数内部的局部变量,完全覆盖了外层提前声明的全局变量,就算回调执行完成,外层的全局变量也不会被修改。
解决方案
你选择将变量挂载为window属性的方式可以解决作用域覆盖问题,实现代码如下:
window.totalActivatedOffers = totalActivatedSparksOffers + totalActivatedRewardsOffers;
如果不想污染全局window对象,也可以采用更规范的实现方式:
- 去掉
setTimeout回调内部的var声明,直接对外层提前声明的totalActivatedOffers赋值,避免创建局部变量覆盖 - 调整代码逻辑,把需要用到
totalActivatedOffers的后续操作封装为函数,放在setTimeout回调的最后调用,保证变量赋值完成后再执行相关逻辑
内容的提问来源于stack exchange,提问作者Chuwa Feet
相关产品推荐
相关产品推荐

