Why can .pop() method change the structure of array that was defined as const variable?

This has been an amazing chat! :grin:

I have a slightly-unrelated-to-.pop()-question -and that is: what determines whether or not a certain dot notation method is mutable ? For instance, why is .splice() mutable and .slice non-mutable? In other words, what factors determine this?

Thank you for your time and reading!

.splice() is an array insertion method, but also deletion. .slice() is a virtual copy of an array or string sequence or segment thereof.

m = 'messesseppi'
n = m.split('')
n.splice(1,7,'i','s','s','i','s','s','i')
m = n.join('')
console.log(m)

Mind, we do have the .replace() method for strings but above we see how the .splice() method works on an array.

1 Like

Thank you very much for your answer @mtf ! This did help clarify things for me a bit:

So, to rephrase, .splice() mutates the array to whatever elements we put in the (…), while .slice() only takes certain elements out and return it to the console?

Another thing is,

how come we needed the (’ ') after join? I tested this out in the console, and saw that without the
quotes, there would be a comma between each letter. Why is this the case? For instance, is that the default?

I appreciate your time in reading and answering my questions, thank you again!

1 Like

A slice can be assigned or used in an expression. It is just a copy, though. That’s the main thing to keep in mind. Slicing has no effect on the original object.

Splicing is in-place mutation of an array. It can only be undone if we know the initial state.

That is called the separator string, in which case the empty string was specified so it comes back to a single word, in our example that was,

mississippi

Leave out the separator string and JS defaults to commas…

m,i,s,s,i,s,s,i,p,p,i
2 Likes

Thank you very much again, @mtf!

Your answer helped clarify any remaining doubts :slightly_smiling_face: Now I understand what the difference between slicing and splicing is, and how join() defaults to commas.

One more question though, and that is

wouldn’t we always be aware of the initial state because we made the array/ can see the previous code? And how exactly would we “undo” a splice -is there a specific example I could refer to?

Thank you again! :+1:

1 Like

We cannot see the array in memory, in real time during a session. It may be very dynamic in nature. It’s up to us inform the code of the data structures it will depend upon.

It follows that we can make a shallow copy of an array (or string) and splice (or use replace, respectively) on the copy, not the original.

a = [1, 2, 3, 4, 5]
z = a.slice()    //  shallow copy
z.splice(3, 2, 5, 8)
console.log(z)    // 1.
z.unshift(1)
console.log(z)    // 2.
z.splice(0, 0, 0)
console.log(z)    // 3.

Output

  1. [ 1, 2, 3, 5, 8 ]

  2. [ 1, 1, 2, 3, 5, 8 ]

  3. [ 0, 1, 1, 2, 3, 5, 8 ]

console.log(a)    //  [ 1, 2, 3, 4, 5 ]

Aha, that makes sense to me that we cannot see the array in memory!

I am still only just grasping this whole slice/splice idea, so your examples are very helpful!

Could you please explain outputs 1 and 3, though? It’s just that the results were different than I expected…

I really appreciate your help again!

Result 1. went to index 3, deleted 2 items, and inserted 2 items. 4, 5 became 5, 8.

Result 3. went to index 0, deleted 0 items, and inserted 1 item, 0.

For now we can ignore that I stuck in the second mutation using a different method. That one will come up in due course, I’m sure.

u = a.slice()
u.splice(0, 0, 0, 1)
u.splice(5, 2, 5, 8)
console.log(u)    //  [ 0, 1, 1, 2, 3, 5, 8 ]
1 Like

Thank you!! The explanations helped me to understand this whole splice process a lot better :bulb:

So then, -using your example- just making sure, if we had

u.splice(6, 1, 9, 10, 11)

then the output would be

[0, 1, 1, 2, 3, 5, 9, 10, 11] ?

In other words, we could add as many numbers after splice(startNum, deleteNum)?

The interpretation looks to be correct. Start index, delete count, items. That’s the gist of this method.

1 Like

That makes sense now, thank you so much for your time and explaining!!

1 Like

I have a question, using .pop to take the elements off a constant array will result in an empty array =

But, then what is the benefit of an empty const array ?

I thought const array means that we cannot change its length or its elements, when i read constant in an array i think about it’s elements same as in constant variables we cannot reassign a new value to a constant variable.

Thanks.

Waheed Berty

Only the array data structure is constant. We can modify the contents all we want, we just can’t delete the array object, itself.

1 Like

Try and think of an array like this, the name of the array would be like the address of a house with many rooms in it. You can change the content inside of the rooms, but cannot change the address of the house itself. (at least while using “const” when declaring the array.

const only protects the array from being deleted or overwritten with a new type, or even a new array. As for the address, every array has a fixed address. No matter how much we alter the contents of the array, the address remains static.

Now, if we use let to declare the array, and then overwrite that with a new array, the address will be different for the new array. It does not get written into the same place in memory as the old array.

a = []

When this statement is parsed and executed, memory is allocated for the array and the address is then stored in memory at another address which is then assigned to the variable. This is rather technical in nature and for best understanding, read up on CALL STACK and HEAP as they relate to JS. Arrays and objects are stored in the heap, Values, and addresses to the objects in the heap are stored in the call stack. The address of those values and addresses is what gets assigned to variables.

1 Like

Hi Roy,

I am new to JS and learning a lot from your answers - appreciate your many helpful contributions to the community!

Can you please amplify on the

while (concept.length) {}

I understand what it does, but I cannot grasp why .length does what it does this. I also seem to be unable to find an answer online.

Thank you in advance!

1 Like

If concept (the object referred by it, that is) is iterable, meaning an array or string then it has a .length property. It is based upon how many elements or characters, respectively, they have.

concept = [1,2,3,4,5,6,7,8,9]

console.log(concept.length)    //  9

There are nine elements in the array.

str = "A quick brown fox jumps over the lazy dog"

console.log(str.length)    //  41

There are 41 characters in the string.


Since an array is a reference object, meaning it contains other references (its elements are all referable, individually) the contents of any element may be any valid data type, whether built in or custom created by the program author, meaning arrays may contain other arrays.

arr = [
  [1, 2],    //  arr[0]
  [3, 4],
  [5, 6],
  [7, 8],
  [9, 10]    //  arr[4]
]

On first glance we see ten number values but that is not the length of the containing array.

console.log(arr.length)    //  5

and the length of the inner arrays which can be accessed by their index in arr are,

console.log(arr[0].length)    //  2
1 Like

Thank you very much for the additional explanation, Roy! Before I read your answer, I was just doing the Looping through Arrays exercise, and think that I managed to grasp the concept thanks to you and

const animals = [‘Grizzly Bear’, ‘Sloth’, ‘Sea Lion’];
for (let i = 0; i < animals.length; i++){
console.log(animals[i]);
}

Cheers :slight_smile:

1 Like