preface

These days in the review of all API js array, is Louis this article, recommended to see! What’s going on? When I reviewed the 12 ways to traverse an array, I found the following sentence:

Traversal methods (12)

“There are 12 ways that ES6 doesn’t change itself, ForEach, Map, every, some, filter, reduce, reduceRight and ES6 newly added methods Entries, find, findIndex, keys and values respectively. “

Note the forEach and map! Why don’t they change the original array? I can remember it all the time!

Let’s go(come, Si dog 😂).

case1:
const objArr1 = [{
    name: 'hn'.age: 12
}]

const objArr2 = [{
    name: 'wx'.age: 13
}]

objArr1.forEach(item= > {
    if (item.name === 'hn') {
      item.age = 82
    }
})
objArr2.map(item= > {
    if (item.name === 'wx') {
      item.age = 83}})console.log(objArr1);  //[{name: 'hn', age: 82}] The original array is changed
console.log(objArr2);  //[{name: 'wx', age: 83}] The original array is changed
Copy the code

Demonstration results

ForEach and map can actually change the array. You think this is the end? Of course with my rigorous character can not end at this point 😄 I again on the Internet query found that there are also a lot of people encounter this problem, suddenly realized! It turns out THAT I omitted the base and reference types! I usually use forEavh and map to refer to data types (objects, arrays, etc.).

Example analysis

Data is of a basic type

  • Change its value (does not change)
const array = [1.2.3.4]; 
array.forEach(item= > { 
    item = item * 3 
}) 
console.log(array); / / [1, 2, 3, 4]
Copy the code

Data is of reference type

  • Changes the value of its property method (changes)
The example is the one above1!
Copy the code
  • Change the item for the entire loop (does not change)
const changeItemArr = [{
    name: 'hn1'.age: 12
}, {
    name: 'hn2'.age: 13
}]
changeItemArr.forEach(item= > {
    if (item.name === 'hn2') {
        item = {
            name: 'hn3'.age: 77}}})console.log(changeItemArr);  // [{name: "hn1", age: 12},{name: "hn2", age: 13}]

Copy the code

There are basic and reference data types in JavaScript. For the basic data types: number, string, Boolean, null, and undefined them directly stored in the stack memory variables and values. However, the real data of Object is stored in the heap memory, and only the Object variables and the corresponding heap address are stored in the stack. Therefore, to operate Object is to directly operate the original array Object itself.

ObjArr1 and objArr2 in forEach and map will actually operate on the address of the object in the heap. As a result, the obJ object in the array will be changed accordingly.

In fact, this reminds me of another knowledge point, shallow copy and deep copy. Shallow copy is the copy of the address of the referenced object, and the change of the copied object will also cause the change of the copied object. So the knowledge points are sometimes the same 🤗️.

extension

Common Solutions

// You can change the base type
const numArr = [13.4.15];
numArr.forEach((item, index, arr) = > {
    if (item === 13) {
        arr[index] = 99}})console.log(numArr);  / / [99, 4, 15]

// You can also change the reference type
const allChangeArr = [{
    name: 'hn1'.age: 12
}, {
    name: 'hn2'.age: 13
}]
allChangeArr.forEach((item, index, arr) = > {
    if (item.name === 'hn2') {
        arr[index] = {
            name: 'hn3'.age: 99}}})console.log(allChangeArr); // // [{name: "hn1", age: 12},{name: "hn3", age: 99}]
Copy the code

You may wonder why arr[index] can be used to change arrays of both primitive and reference types. The reason is that fn passes (item, index, arr) when calling forEach and map methods. If you remember their arguments fn’s arguments contain three that are currentValue (required. Current element), index (optional. Index value of the current element), arR (optional. The arR is the original array object, so it has no right to change itself. Inside the Saoga Temple! 😏