Safari下JavaScript async函数参数返回undefined问题
问题根源
和Safari支不支持异步函数参数无关,是代码里重复声明同名变量触发的变量提升兼容问题。
你在函数形参里已经定义了title、message、button三个入参,函数内部又用var声明了三个完全同名的变量。Safari(尤其是15及更早版本)的JavaScript引擎对async函数的作用域处理有历史实现差异:async函数内用var声明和形参同名的变量时,变量提升会直接把形参传入的值覆盖为undefined,而Chromium内核的Edge、Chrome没有这个问题,这就是你在Safari里读不到参数值的核心原因。
你函数第一行写的alert(title + ' ' + message + ' ' + button);在Safari里弹出undefined,本质是下面三行var声明被提升到了函数最顶部,执行alert的时候形参值已经被覆盖了。普通函数不存在这个作用域处理差异,所以你测试的普通函数传参能正常读取。
修复方法
二选一即可:
- 直接删掉内部变量前的
var关键字,复用形参变量赋值,从根源避免同名声明冲突,核心修改部分如下:
async function openDialogInfo(title, message, button) { // 去掉var,直接操作形参,不会触发提升覆盖 title = (typeof title !== 'undefined') ? encodeURI(title) : 'Information'; message = (typeof message !== 'undefined') ? encodeURI(message) : 'Error retrieving message !'; button = (typeof button !== 'undefined') ? encodeURI(button) : 'Ok'; // 原有逻辑不需要改动,注意如果要alert原始文本记得decodeURI,否则会显示编码后的内容 alert(decodeURI(title) + ' ' + decodeURI(message) + ' ' + decodeURI(button)); if (title.length >= 3 && message.length >= 5 && button.length >= 3) { if (screen.width >= 720) { $("#out-popup-e").css({ 'opacity': '0' }).show(); } else { $("#out-popup-e").show(); } var params = `title=${title}&message=${message}&bouton=${button}`; var resp = await fetch('../../../popup/popup_ecars_info.php', { method: "POST", body: params, headers: { "Content-type": 'application/x-www-form-urlencoded' } }); var out = await resp.text(); if (resp.status == '200') { if (screen.width >= 720) { $("#out-popup-e").animate({ 'opacity': '1' }, 400).html(out); } else { $("#out-popup-e").html(out); $(".center-popup").css({ 'bottom': '-700px' }).animate({ 'bottom': '0' }, 400); } } else { console.error('Error Message 2'); } } else { console.error('Error message 1'); } }
- 如果要保留独立的内部变量,直接换个不重名的命名即可,比如把编码后的参数命名为
encodedTitle、encodedMessage、encodedButton,避开和形参同名的问题。
补充提示
你给出的测试调用代码里只传了前2个参数,第三个button参数本身就会是undefined,走默认值逻辑属于正常情况,不是bug。
内容的提问来源于stack exchange,提问作者Meteoff Dev
相关产品推荐
相关产品推荐

