首页 > 解决方案 > 实例化和推送新对象后,数组中的每个对象都会被覆盖

问题描述

我正在尝试根据用户输入制作一组对象。

对象被推入数组,但在下一步输入覆盖数组中的每个对象。

我试过通过category.value并且效果很好,但我想通过整个类别。

例如:

  1. 选择 A,提交,输出 - “a”(如预期)
  2. 选择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>

标签: javascript

解决方案


在您的代码中,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>


推荐阅读