javascript - 实例化和推送新对象后,数组中的每个对象都会被覆盖
问题描述
我正在尝试根据用户输入制作一组对象。
对象被推入数组,但在下一步输入覆盖数组中的每个对象。
我试过通过category.value
并且效果很好,但我想通过整个类别。
例如:
- 选择 A,提交,输出 - “a”(如预期)
- 选择B,提交,输出-“b”,“b”(预期“a”,“b”)
为什么会这样?
let form = document.getElementById('form');
let category = form.category;
let submit = document.getElementById('formSubmit');
let arr = [];
submit.addEventListener("click",(e)=>{
e.preventDefault();
let c = new C(category);
arr.push(c);
for(let i=0;i<arr.length;i++)
{
console.log(arr[i].category.value);
}
})
class C {
constructor(category)
{
this.category = category;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<form id="form">
<select name="category">
<option value="-">choose category</option>
<option value="a">A</option>
<option value="b">B</option>
<option value="c">C</option>
</select>
<button id="formSubmit" type="submit">submit</button>
</form>
<script src="test.js"></script>
</body>
</html>
解决方案
在您的代码中,let category 是对您选择的 HTML 元素(而不是 Javascript 对象)的直接引用。此引用被推送到数组中。每次您要求值时,您都会直接从您的选择中获取 value 属性。所以它每次都会更新。
如果您想要一个具有该值的 Javascript 对象,则必须构造一个并将其提供给您的类:
let form = document.getElementById('form');
let category = form.category;
let submit = document.getElementById('formSubmit');
let arr = [];
submit.addEventListener("click",(e)=>{
e.preventDefault();
let c = new C({ value: category.value });
arr.push(c);
for(let i=0;i<arr.length;i++)
{
console.log(arr[i].category.value);
}
})
class C {
constructor(category)
{
this.category = category;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<form id="form">
<select name="category">
<option value="-">choose category</option>
<option value="a">A</option>
<option value="b">B</option>
<option value="c">C</option>
</select>
<button id="formSubmit" type="submit">submit</button>
</form>
<script src="test.js"></script>
</body>
</html>
请注意,它之所以有效,是因为 Javascript 中的字符串是按值传递的,而对象是按引用传递的(实际上是引用的值)。如果您有一个全局类别对象,您更新了值并将其推送到数组中,您将遇到同样的问题:
let form = document.getElementById('form');
let category = form.category;
let categoryObj = { value: null };
let submit = document.getElementById('formSubmit');
let arr = [];
submit.addEventListener("click",(e)=>{
e.preventDefault();
categoryObj.value = category.value;
let c = new C(categoryObj);
arr.push(c);
console.log('same problem you had because all items in the array are the same reference to the global object!');
for(let i=0;i<arr.length;i++)
{
console.log(arr[i].category.value);
}
})
class C {
constructor(category)
{
this.category = category;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<form id="form">
<select name="category">
<option value="-">choose category</option>
<option value="a">A</option>
<option value="b">B</option>
<option value="c">C</option>
</select>
<button id="formSubmit" type="submit">submit</button>
</form>
<script src="test.js"></script>
</body>
</html>
推荐阅读
- tcp - Influxdb 不关闭 TCP 连接
- javascript - 是否可以使用 JS 正则表达式向 html 添加格式
- c# - 反序列化 JSON 错误将值转换为特定类型
- c# - 为每个员工支付的金额到期
- javascript - 在javascript中鼠标移出时使信息窗口消失
- vb.net - 在运行时动态更改控件的 ContextMenuStrip 属性?
- r - 使用 if 语句和相似数量的样本进行 R 采样
- python - 创建一个基本的 Python 接口来保存用鼠标绘制的图像
- jquery - 来自 AJAX 调用的 Jquery 更改表值
- maven - Java11 / JavaFX 和 Maven 不会在 NetBeans IDE 9 之外运行