类中的数组
我正在尝试制作一个媒体寄存器,允许用户提交存储在数组中的书籍或电影。这是我目前所拥有的:
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(title) {
this.title = [];
}
}
class Book extends Media {
constructor(title, author, pages) {
super(title);
this.author = [];
this.pages = [];
}
insert() {
title.push(titleInput.value);
author.push(authorInput.value);
pages.push(pagesInput.value);
clearAndShow();
}
clearAndShow() {
titleInput.value = "";
authorInput.value = "";
pagesInput.value = "";
displayBox.innerHTML = "";
displayBox.innerHTML += "Title: " + title.join(", ") + "<br/>";
displayBox.innerHTML += "Author: " + author.join(", ") + "<br/>";
displayBox.innerHTML += "Pages: " + pages.join(", ") + "<br/>";
}
}
class Movie extends Media {
constructor(title, director, runTime) {
super(title);
this.director = [];
this.runTime = [];
}
insert2() {
title2.push(title2Input.value);
director.push(directorInput.value);
runTime.push(runTimeInput.value);
clearAndShow2();
}
clearAndShow2() {
title2Input.value = "";
directorInput.value = "";
runTimeInput.value = "";
displayBox2.innerHTML = "";
displayBox2.innerHTML += "Title: " + title2.join(", ") + "<br/>";
displayBox2.innerHTML += "Director: " + director.join(", ") + "<br/>";
displayBox2.innerHTML += "Run Time: " + runTime.join(", ");
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<div class="tab">
<button class="tablinks" onclick="openMedia(event, 'Book')">Book</button>
<button class="tablinks" onclick="openMedia(event, 'Movie')">Movie</button>
</div>
<div id="Book" class="tabcontent">
<form id="tabcontent" name="myForm" class="bookContainer" onsubmit="return(validate());">
<label for="Title">Title:</label>
<input id="title" type="text" placeholder="Book title">
<small class="error"></small>
<br>
<label for="Author">Author:</label>
<input id="author" type="text" placeholder="Author's name">
<small class="error"></small>
<br>
<label for="Pages">Pages:</label>
<input id="pages" type="text" placeholder="Amount of Pages">
<small class="error"></small>
<br>
<button onclick="insert()" id="submit-btn" type="submit">Submit</button>
</form>
<div id="display">
<h3> </h3>
</div>
</div>
<div id="Movie" class="tabcontent">
<form name="form2" class="movieContainer" onsubmit="return(validate());">
<label id="" for="Title">Title:</label>
<input id="title2" type="text" placeholder="Movie title">
<small class="error"></small>
<br>
<label for="Director">Director:</label>
<input id="director" type="text" placeholder="Director's name">
<small class="error"></small>
<br>
<label for="runTime">Runtime:</label>
<input id="runTime" type="text" placeholder="Runtime of movie">
<small class="error"></small>
<br>
<button onclick="insert2()" id="submit-btn" type="submit">Submit</button>
</form>
<div id="display2">
<h3></h3>
</div>
</div>
</div>
<script src="main.js"></script>
</body>
</html>
我认为这是正确的方法,但最终我得到了范围错误。请查看此处的代码笔: https://codepen.io/nstersleep/pen/GRMRzpo?editors=0011
我的问题是,如何让保存所有用户值的数组在类中工作?这是我第一次做这样的事情!
正如我所评论的,这个问题是不完整的,但主要问题是您在引用类中的属性和方法时缺少
this.
。JavaScript 没有像 Java 和 C# 那样隐含的
this
,它必须始终是显式的。因此,例如,在
Book
的
insert
中,您需要
this.title.push(titleInput.value);
^^^^^
如果没有它,您将尝试使用不存在的作用域内变量 (
title
)。
对于
clearAndShow
等方法调用也是如此。
但其他一些事情也跳出来了:
-
您有未用于任何用途的构造函数参数。只需将其删除即可。
-
我不会通过让类关闭输入元素变量来将类绑定到输入元素。相反,将要使用的输入元素传递到类构造函数中。
-
像您的
title
、author
和pages
这样的并行数组很脆弱,很容易修改其中一个而不修改其他,从而导致不匹配。相反,使用具有标题、作者和页面属性的对象数组。 -
Book
和Movie
是单数,但您使用它们来保存多本书和多部电影(复数)。如果您想这样做,使用复数形式(Books
、Movies
)或某些表示它们是容器的名称(BookStore
、MovieStore
)会更有意义。 -
Movie
的insert
和clearAndShow
方法没有理由需要与Book
有不同的名称。 -
Book
和Movie
实际上没有多大用处。毕竟,它们实际上只是数组。相反,我会有一个代表一本书的Book
类(具有title
、author
和pages
属性)和一个代表一部电影的Movie
类(具有title
、directory
和runtime
属性)。(如果您愿意,它们可以从具有title
的Media
类继承。)然后只需保留一个Book
实例数组和一个Movie
实例数组即可。
以下是最后一点的简要概述:
class Media { // If you want it, it doesn't add much value with just the one property
constructor(title) {
this.title = title;
}
}
class Book extends Media {
constructor(title, author, pages) {
super(title);
this.author = author;
this.pages = pages;
}
}
class Movie extends Media {
constructor(title, director, runTime) {
super(title);
this.director = director;
this.runTime = runTime;
}
}
const books = [];
const movies = [];
// Adding a book:
books.push(new Book(titleInput.value, authorInput.value, pagesInput.value));
// Adding a movie:
movies.push(new Movie(titleInput.value, directorInput.value, runTimeInput.value));
提交时,您尝试调用超出范围的插入函数,因为插入是在 Book 类中定义的,而不是在全局范围内。
<button onclick="insert()" id="submit-btn" type="submit">Submit</button>
添加一个可以从 html 调用的调用者函数。此调用者函数将构建 book 类的对象,然后调用 Book 对象的 insert()。
示例可能如下 -
function submitBook() {
var book = new Book(titleInput);
book.insert();
book.clearAndShow();
}
然后从 HTML 调用它,如下所示
<button onclick="submitBook()" id="submit-btn" type="submit">Submit</button>
另一点是 - 请使用 this 关键字为您的函数中的变量分配/读取值,如第一个答案中所述。例如 -
this.title.push(titleInput.value);