Array.prototype.map() returns empty item but Array.prototype.forEach() doesn't

时间:2018-09-18 19:35:08

标签: javascript arrays object foreach array.prototype.map

I experience a weird behaviour from .map(). It returns an empty item whilst .forEach() doesn't.

Here's the code:

class Entry {
    constructor(data) {
        this.name = data[0],
        this.age = data[1],
        this.school = data[2]
    };

    get organised() {
        return this.organise();
    };

    organise() {
        const data = {
            name: this.name,
            school: this.school
        };
        return data;
    }
}

const getDataForEach = (obj) => {
    let r = [];
    obj.forEach((i) => {
        const e = new Entry(i);
        r.push(e.organised);
    });
    return r;
};
getDataForEach(input); // return normal object array [{...}, {...}, ...]

But if I use .map(), it returns an object array with the first item is empty. The other items are the same as result from .forEach().

const getDataMap = (obj) => {
    return obj.map((i) => {
        const e = new Entry(i);
        console.log(e) // return normal [{...}]
        console.log(e.organised) // return normal {...}
        return e.organised;
    });
};
getDataMap(input); // return an object array with the first item empty [<1 empty item>, {...}, {...}, ...]

Have you experienced anything similar to this?

1 个答案:

答案 0 :(得分:4)

When processing a sparse array, both map and forEach() skip elements that have never been assigned or have been deleted.

The difference, though, is that map constructs the resulting array itself, while your forEach() code is pushing onto the result array. push() will never create holes in the array, since it always appends a new element at the current length, but map() can. MDN points out:

Due to the algorithm defined in the specification if the array which map was called upon is sparse, resulting array will also be sparse keeping same indices blank.

You would get a result similar to map if you changed the forEach code to use the input array indices rather than using push, e.g.

const getDataForEach = (obj) => {
    let r = [];
    obj.forEach((i, index) => {
        const e = new Entry(i);
        r[index] = e.organised;
    });
    return r;
};
相关问题