Just to clear up something about .push()

This is a code i found on this forum and something caught my attention!
Here is the code:

function rangeOfNumbers(startNum, endNum) {
  if (endNum == startNum) {
    return [startNum];
  } else {
    /*startNum = startNum <= endNum;*/
    const myArray = rangeOfNumbers(endNum - startNum);
    myArray.push(endNum);
    myArray.unshift(startNum);
    return myArray;
  }
}

So this guy is trying to push a value to a const myArray which is a function call, now i know that you can push things to an array. Does declaring myArray as a const makes it an array? Or is the usage of .push is wrong here?
Thank you.

He is not wrong, though it seems completely backwards, doesn’t it? You would be absolutely right if he were doing something like

myArray = [...myArray, endNum];

as that would be assigning a completely new array to a const variable. But non-primitive values stored in a variable act a little differently: the only thing about them that is const by default is the actual reference to the array or object itself, not the contents of that non-primitive thing.

So long as you leave the “array container” (the []) or the object container (the {} itself alone, you can usually add array members or object properties as you like.

The MDN Docs on the subject are interesting (referenced here from DevDocs):

The const creates a read-only reference to a value. It does not mean the value it holds is immutable—just that the variable identifier cannot be reassigned. For instance, in the case where the content is an object, this means the object’s contents (e.g., its properties) can be altered.

What that’s saying is, the place in memory that our value starts is the only thing fixed in that const. The “wire” between the variable and that location in memory is locked with a const, but that doesn’t prevent the internals of a non-primitive from being tinkered with.

In short, the const prevents you from reassigning a value to that particular variable. It doesn’t guarantee that the internals of that value will remain the same.

3 Likes

it should be noted, in case you are not aware, this is recursion, as the function rangeOfNumbers is called within itself. The function is designed in such a fashion that it always return an array. When you say const someName=rangeOfNumbers(some proper parameters) , we call the function, which returns an array as result and that array we assign to the variable name. After that we can proceed calling push, unshift or whatever array method on it, as snowmonkey pointed out above, the const keyword allows us to mutate the value, but not reassign it a another value(we cant explicitely modify it using the ‘=’ operator).
You can try console.log() the value of myArray after its declared(before push()) and you will see it represents an array

2 Likes

Thanx to both of you, now not only do i know that recursive function’s inside call returns an array(which what i was looking for to understand) but thanx to @snowmonkey i know what const does.
Which bring the question: what const stand for? Is it short for constant?
I would wanna ask what is it used for but i think you answered part of that.

It does stand for constant, yes. Because the memory reference assigned to the variable is a constant value.

We don’t assign values to variables, we “wire” a variable to a particular location in the browser’s memory. And with a var or let, when we re-assign a value, like this:

// here we point to a particular location in memory...
let myName = "snowmonkey";

// ... but when we evaluate the .toUpperCase, we place that at a different location
//   in memory, and we wire to that instead.
myName = myName.toUpperCase();

With a const, that “rewiring” cannot happen - the assignment itself is fixed at declaration with a const. That’s why you can’t do this:

const myName;
// Uncaught SyntaxError: Missing initializer in const declaration
1 Like

You mean now that i already declared myName with ‘let’ and modified it with .toUpperCase ( the re-wiring), i can not do this : const myName;

Right? Just wanna get you clearly.

Two separate concepts entirely. In the first case, we are re-wiring myName from one memory location to another.

in the second case, as an entirely separate codebase, we are creating a const but not assigning it a value at instantiation. That is the source of the error.

To be clear recursion is when a function is called within itself.

function countDown(fromNumber) {  //we define the function here
    console.log(fromNumber);

    let nextNumber = fromNumber - 1;

    if (nextNumber > 0) {
        countDown(nextNumber);  //we call the function within itself
    }
}

countDown(3);  //execute the function
// logs 3
// logs 2
// logs 1

The fact rangeOfNumbers() was always returning an array, is because the way its designed, not because its recursive.

PS: the countdown recursion i looked up online

1 Like

I’ve edited your post for readability. When you enter a code block into a forum post, please precede it with a separate line of three backticks and follow it with a separate line of three backticks to make it easier to read.

You can also use the “preformatted text” tool in the editor (</>) to add backticks around text.

See this post to find the backtick on your keyboard.
Note: Backticks (`) are not single quotes (’).

Just to be clear…

This doesn’t work because you are trying assign a new number literal with a new address to a constant:

const num = 123;
num = 42; // error

This works because arrays are reference (memory address) types and we are not changing the reference, only the data contained at that reference:

const myArr = [1, 2, 'oops'];
myArr[2] = 3;
myArr.push(4);

That last one worked because myArr is always pointing to a single reference, a single place in memory. We’re only changing the values at that place in memory. This does not violate the “const” rule, which only says that the “variable” cannot be reassigned. With a reference type (objects, arrays, etc.), the “variable” is the address and there just happens to be stuff at that location. The stuff at that location can be changed, no problem.

This will not work because it is trying to change where the variable points. The array literal ([1, 2, 3]) is being created in a new location of memory and JS is trying to store that new address in myArr. But it can’t because we can’t change what myArr contains (in this case, the reference/address).

const myArr = [1, 2, 'oops'];
myArr = [1, 2, 3]; // error
1 Like

thank you @jwilkins.oboe, i posted this from my phone forum app, it didn’t have those options ( separate line of three backticks)for embedding code like you did so.

You can use the preformatted text tool on your phone. Just like the video shows you

I think that appears in the browser, but when you open the forum app that you add to your home screen, i shows this:

no options to choose from.

When I click on the icon I circled in screenshot the options appear for me on the phone

got it, it worked, thank you.

1 Like

do you think a recursion function call returns an array or just a simple value?

Just like any function, a recursive function returns what it has been written to return. The countdown function you reference, when it reaches its innermost recursive call, should return an empty array. Then as each return gets passed to the next outer, it inserts a value into that array, and keeps passingit along.

In many ways, a recursive function does much the same as a Array.reduce() - given a collection of data points, merge then into some single thing, whether a number, string, object or array.

1 Like

take a look at this:
when I console.log the array of inside call of the function, gives me only an array of 2,4,6,8,10 where the count is from 10 to one. why?

I have no idea what that piece of code is doing.

Please don’t use var. You get confusing results.

I don’t see a base case or any use of the returned value from the recursive function call. Is there more code that modifies array?

1 Like

What’s in the first 15 lines? What is your recursive exit condition? What does that countdown explicitly return?

Seems there are missing parts, imo.

1 Like