在映射之前修改数组项。请解释一下

时间:2019-10-03 21:00:24

标签: javascript

我正在编写一个JavaScript类,并且有一个名为“ options”的JSON对象变量,在这里我正在修改该变量的“ items”数组。

class CustomDropdown {

    constructor(opt) {
        this.options = {
            element: opt.element,
            name: opt.name,
            multiChoice: opt.multiChoice === true,
            callbacks: [],
            items: opt.items.map(i => {
                const text = i.text || "";
                const it = {
                    text: text,
                    value: (i.value || text).replace(/[^A-Za-z0-9\_\-\ ]/g, "").trim(),
                    selected: (i.selected === true && i.selected !== undefined)
                };

                console.log("json obj in map func:", it);
                return it;
            })
        };

        console.log("after:", this.options.items);

        //this seems to be the function messing things up.
        this.fixSelectedItems();
    }

    fixSelectedItems() {
        const itemsBefore = this.options.items;
        this.debug("Fixing the items, before:", itemsBefore);
        if(!this.options.multiChoice) {
            let hasSelectedItem = false;
            this.options.items = this.options.items.map(i => {
                if(i.selected === true) {
                    if(selectedItem === null) {
                        hasSelectedItem = true;
                    } else {
                        i.selected = false;
                    }
                }
                return i;
            });

            if(!hasSelectedItem) {
                this.options.items[0].selected = true;
            }
        }
        this.debug("Fixed the items, after:", this.options.items);
    }

}

因此,在开发工具控制台中不调用this.fixSelectedItems()打印将导致以下情况:

json obj in map func: {text: "hm...", value: "hm", selected: false}
json obj in map func: {text: "none", value: "wow", selected: false}
json obj in map func: {text: "omg again", value: "omg again", selected: false}
after: [{text: "hm...", value: "hm", selected: false}, {text: "none", value: "wow", selected: false}, {text: "omg again", value: "omg again", selected: false}]

但是调用this.fixSelectedItems()之后,在登录控制台this.options.items后将选中的this.options.items中的第一个JSON对象设置为true。但是在此之前,所有这些对象都应该为false如果可以的话,将调用该函数。

json obj in map func: {text: "hm...", value: "hm", selected: true}
json obj in map func: {text: "none", value: "wow", selected: false}
json obj in map func: {text: "omg again", value: "omg again", selected: false}
after: [{text: "hm...", value: "hm", selected: true}, {text: "none", value: "wow", selected: false}, {text: "omg again", value: "omg again", selected: false}]
Fixing the items, before: [{text: "hm...", value: "hm", selected: true}, {text: "none", value: "wow", selected: false}, {text: "omg again", value: "omg again", selected: false}]
Fixing the items, after: [{text: "hm...", value: "hm", selected: true}, {text: "none", value: "wow", selected: false}, {text: "omg again", value: "omg again", selected: false}]

很抱歉,如果这看起来有点混乱,但我只是感到困惑。 为什么在调用函数之前在修改数组后调用this.fixSelectedItems()?是数组映射吗?

顺便说一句this.debug只是console.log。

1 个答案:

答案 0 :(得分:1)

日志中显示的对象是对实际对象本身的引用,因此,如果在查看日志之前对记录的对象进行了编辑,它将显示该对象的当前版本,而不是当时的状态记录。

如果将控制台日志更改为以下内容(以便在该状态下“深度克隆”该对象,而不是记录对该对象的引用),则会看到所需的日志。尽管值得注意的是问题仅在于日志,但是您的代码将按预期工作。

console.log("json obj in map func:", JSON.parse(JSON.stringify(it)));