使用addEventListener时对象属性返回undefined的问题
表单处理函数返回undefined的原因与解决办法
问题核心原因
handleName和handleAuthor返回undefined的本质是值传递与引用传递的区别:
- 这两个函数里,你返回的是
project.name/project.author——这属于字符串类型的原始值,函数执行时change事件还未触发,所以初始值就是undefined。后续事件触发时给project.name赋值,不会改变已经返回的那个undefined,因为原始类型是按值传递的,返回后就和原变量断开了联系。 - 而
handleSD返回的是project.sd这个对象,对象是引用类型,函数返回的是对象的内存地址。后续事件触发时修改对象的属性,会直接反映到这个引用上,所以外部能拿到更新后的值。
解决方案
方案1:统一返回对象(和handleSD风格一致)
让handleName/handleAuthor返回包含属性的对象,利用引用传递特性同步更新:
export function handleName() { const data = { name: null }; const txt_name = document.getElementById("name"); // 同步输入框初始值(如果有默认值的话) data.name = txt_name.value; txt_name.addEventListener("change", () => { data.name = txt_name.value; }); return data; } export function handleAuthor() { const data = { author: null }; const txt_author = document.getElementById("author"); data.author = txt_author.value; txt_author.addEventListener("change", () => { data.author = txt_author.value; }); return data; }
调用时调整为:
window.addEventListener("DOMContentLoaded", () => { // ...其他代码 project.name = handleName().name; // 或者如果需要实时同步,直接让project.name指向返回的对象: // project.name = handleName(); // 后续取project.name.name即可 });
方案2:闭包维护状态,提供取值方法
通过闭包保存最新值,返回一个获取值的方法:
export function handleName() { let currentValue = document.getElementById("name").value; const txt_name = document.getElementById("name"); txt_name.addEventListener("change", () => { currentValue = txt_name.value; }); return { getValue: () => currentValue }; }
调用时:
const nameHandler = handleName(); // 需要获取最新值时调用 const latestName = nameHandler.getValue();
方案3:直接操作全局project对象
如果允许函数直接修改全局的project,也可以去掉返回值,直接在事件里更新:
export function setupNameInput(project) { const txt_name = document.getElementById("name"); project.name = txt_name.value; // 同步初始值 txt_name.addEventListener("change", () => { project.name = txt_name.value; }); }
调用时:
window.addEventListener("DOMContentLoaded", () => { // ...其他代码 setupNameInput(project); setupAuthorInput(project); });
内容的提问来源于stack exchange,提问作者Pedro Toriality
相关产品推荐
相关产品推荐

