如何在JavaScript类中使用数组存储媒体数据并解决作用域报错问题
问题根因
- 类内访问实例属性必须加
this前缀,你现在直接写title.push(),浏览器会找全局的title变量,自然报未定义的作用域错误 - 你只定义了
Book和Movie类,没有实际创建实例,页面上绑定的onclick="insert()"调用的是全局函数,和类内的insert方法完全不关联 - 表单默认提交会刷新页面,提交之后数据会被清空
- 缺少tab切换的
openMedia函数,页面基础交互无法正常运行
修正后的完整JS代码
let titleInput = document.getElementById("title"); let authorInput = document.getElementById("author"); let pagesInput = document.getElementById("pages"); let title2Input = document.getElementById("title2"); let directorInput = document.getElementById("director"); let runTimeInput = document.getElementById("runTime"); let displayBox = document.getElementById("display"); let displayBox2 = document.getElementById("display2"); class Media { constructor() { this.title = []; } } class Book extends Media { constructor() { super(); this.author = []; this.pages = []; } insert(e) { // 阻止表单默认提交刷新页面 e?.preventDefault(); this.title.push(titleInput.value); this.author.push(authorInput.value); this.pages.push(pagesInput.value); this.clearAndShow(); } clearAndShow() { titleInput.value = ""; authorInput.value = ""; pagesInput.value = ""; displayBox.innerHTML = ""; displayBox.innerHTML += "Title: " + this.title.join(", ") + "<br/>"; displayBox.innerHTML += "Author: " + this.author.join(", ") + "<br/>"; displayBox.innerHTML += "Pages: " + this.pages.join(", ") + "<br/>"; } } class Movie extends Media { constructor() { super(); this.director = []; this.runTime = []; } insert2(e) { e?.preventDefault(); this.title.push(title2Input.value); this.director.push(directorInput.value); this.runTime.push(runTimeInput.value); this.clearAndShow2(); } clearAndShow2() { title2Input.value = ""; directorInput.value = ""; runTimeInput.value = ""; displayBox2.innerHTML = ""; displayBox2.innerHTML += "Title: " + this.title.join(", ") + "<br/>"; displayBox2.innerHTML += "Director: " + this.director.join(", ") + "<br/>"; displayBox2.innerHTML += "Run Time: " + this.runTime.join(", "); } } // 实例化类,把方法挂载到全局供页面调用 const bookShelf = new Book(); const movieList = new Movie(); function insert(e) { bookShelf.insert(e); } function insert2(e) { movieList.insert2(e); } // 补充tab切换逻辑 function openMedia(evt, mediaType) { let i, tabcontent, tablinks; tabcontent = document.getElementsByClassName("tabcontent"); for (i = 0; i < tabcontent.length; i++) { tabcontent[i].style.display = "none"; } tablinks = document.getElementsByClassName("tablinks"); for (i = 0; i < tablinks.length; i++) { tablinks[i].className = tablinks[i].className.replace(" active", ""); } document.getElementById(mediaType).style.display = "block"; evt.currentTarget.className += " active"; }
改动说明
- 移除了类构造函数中无用的传参,所有属性都用
this.xxx定义为实例属性,调用时也统一加this前缀 - 新增类实例化逻辑,把实例方法包装为全局函数供页面的
onclick事件调用 - 新增阻止表单默认提交的逻辑,避免页面刷新丢失数据
- 补充了缺失的
openMediatab切换函数,保证页面基础交互正常 - 如果需要表单校验逻辑,自行补充
validate函数的实现即可,当前代码已经可以正常完成信息提交、存储、展示的核心功能
内容的提问来源于stack exchange,提问作者Nster
相关产品推荐
相关产品推荐

