我正在尝试根据用户输入创建对象数组。
该对象被推入数组,但是在下一步,输入将覆盖数组中的每个对象。
我尝试通过category.value
,并且效果很好,但是我想通过整个类别。
例如:
为什么会这样?
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>
答案 0 :(得分:1)
是对您选择的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>
答案 1 :(得分:0)
category
对象是整个程序中的同一对象,用户输入只是对其进行更改。当用对象填充数组时,它们实际上是按引用存储的,因此代码中发生的事情是同一对象填充了数组。这就是为什么您遇到描述的重复的原因。
如果相反,您做了例如像这样:
let arr = [];
submit.addEventListener("click",(e)=>{
e.preventDefault();
let c = new C(category);
arr.push(c.category.value);
for(let i=0;i<arr.length;i++)
{
console.log(arr[i]);
}
});
然后使用实际值填充数组,您将获得期望的结果。如果您想专门存储C实例,可以通过例如在推入数组之前先cloning个对象。