0

Hi stackoverflow people :)

I'm a web developer diving in some JavaScript concepts.

I was reading ECMA docs and MDN to get really understanding of lexical environments, executions contexts, closures and memory management but I really got stuck in this topic.

EX:

const x = 1;

let y = x;

y = 2;

As far as I understand, 1 and 2 are primitives so immutable and every time I re-assign a variable, behind the scenes I'm changing the reference. So, in line 2, y and x are pointing to same value.

And here comes my headache: where is that value? Am I just pushing to the stack two references to the number 1 (in this case)?

I don't get if each primitive will have same memory's address for all the execution of the program or which is the behavior behind that.

There is so many information and I don't know in who I can trust because in large cases the information is contradictory haha.

Thanks for your time guys, and to be honest I'm learning English too so I hope you could understand me :)

IRONM00N
  • 1,105
  • 4
  • 17
  • 1
    Exactly where that value is stored is not covered by the spec. Different implementations can choose to store the value in different ways. For example, naive implementations may actually allocate a heap object for each new mention of "1". Slightly less naive implementations may allocate a single heap object to represent all "1"s. Even fancier ones may avoid the heap allocation altogether by using discriminated unions. And super-fancy ones may embed the discriminator inside the data itself. All of these implementations are valid, provided they support the operations in the spec. – Raymond Chen Nov 27 '21 at 01:41

3 Answers3

0

Find out by using the Console in your browser

Open the Console in your browser

In most browsers pressing F12 opens the Console. If that doesn't work, then find the menu or submenu named Developer tools and click it.

Select the Console tab

Make sure the tab named Console is selected. Click it.

Create your test

Then type the statements you want to test into the Console.
For example:

const x = 1;
let y = x;
y = 2;

Show the results

Then type the following to show the result of your test - what you want to know:

[x,y]

Or:

console.log(x,y)

The result shows that x and y don't reference the same number.

Here is the output of typing [x,y]:

Array [ 1, 2 ]

And here is the output of typing console.log(x,y):

1 2

The result shows that assigning to y doesn't affect x.

Rinse and repeat

Do something similar the next time you get in doubt about how it works.

-1

There are primitive types (like number, boolean, string...) and complex types (object, array) in Javascript. So they will behave a little bit differently:

const x = 1; <- Assign the primitive value 1 to the variable x (somewhere in the memory heap)

let y = x; <- Assign the value of the variable 1 to the variable y (somewhere in the memory heap). Here, you will have 2 different pieces of memory, each for one of the vars.

y = 2; <- Change the value of the second variable to 2.

When you talk about memory addresses and pointers, you are talking mostly about complex types. Here, when you define an object, that object is stored in the heap, if you assign that object to another variable then you are pointing to the same value. An example:

const x = {a:1} <- Create the object and assign a reference to x

const y = x; <- Assign the same reference to y

y.a = 2 <- Change the value of the object.

console.log(x.a) <- will return 2.

For more information take a look at this website

Robert Mengual
  • 374
  • 3
  • 10
-1

The identifiers used for variables have a location where their value is stored, making them "lvalues" in that they can appear on the left hand side of an assignment expressions.

Because JavaScript is interpreted, a record of the name of the identifier and where it is stored needs to be maintained by the JavaScript engine. In standards that record is known as a "binding" of the name and is held in an environment record. Obtaining the value of a variable then looks up the binding of the its name to get its value. (Step 6 of a GetValue operation in standards)

So in the example

const x = 1;

let y = x;

y = 2;

x and y have different locations in an environment record.

Now JavaScript is loosely typed, meaning a variable can hold values of any data type supported in JavaScript. By implication, the representation of a value must hold information about it's type as well as its actual value.

This is the point at which people start to guess or hypothesize how (primitive) values are held internally by the JavaScript engine. You may have come across statements like "everything" in JavaScript is implemented as an internal (native code) object and passed around as a pointer. This assumption appears in the question:

So, in line 2, y and x are pointing to same value.

This is not necessarily true for all JavaScript engines. JavaScript programmers have no control over how the engine actually implements primitive values, and assuming a "pointer to internal object" model may be incorrect. One alternative I know of involves using tagged NaN values to convey non numeric information: with 16,777,214 different thirty two bit NaN values (more for 64 bit floating points), there are ample separate values that could be used for undefined, boolean and null values etc. Such an approach has the potential of avoiding the need to hold data type and value as separate properties of an internal object.

In regards

Does each primitive will have same memory's address for all the execution of the program?

it will depend on the efficiency, optimization and implementation of values by the JavaScript engine. Anecdotally some engines will attempt to consolidate string primitives and not create multiple multiple copies of the same string value but how good they are at doing that is another question. Whether other kinds of primitives have an address at all goes back to internal implementation.

traktor
  • 17,588
  • 4
  • 32
  • 53