You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在JavaScript类中使用数组存储媒体数据并解决作用域报错问题

问题根因

  1. 类内访问实例属性必须加this前缀,你现在直接写title.push(),浏览器会找全局的title变量,自然报未定义的作用域错误
  2. 你只定义了Book和Movie类,没有实际创建实例,页面上绑定的onclick="insert()"调用的是全局函数,和类内的insert方法完全不关联
  3. 表单默认提交会刷新页面,提交之后数据会被清空
  4. 缺少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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 12:15:05