Unusual quirks in javascript variables when used with arrays

Unsure if this question has been asked previously. Nevertheless, I couldn't find it anywhere. I've observed a peculiar behavior that seems to occur only with arrays.

Here is the typical behavior I anticipate from variables:

var k = 10,
    m = k;
alert(m); //10
k+=1;
alert(m); //10

Now, observe how they behave when dealing with arrays.

var arr = [],
    arr2 = arr;
alert(arr2); // empty
arr.push(1);
alert(arr2); // 1

It appears that with arrays, variables are merely references to the same array, while with numbers, they signify two distinct numbers that happen to have the same value.

I apologize if this seems like a beginner's question, but I recently made this observation. Does this apply to all complex types? Also, what is the rationale behind this behavior? What purpose does the language serve by implementing it in this manner?

Answer №1

The initial state of the first code block shows:

m = k;

This line copies the value from variable k to variable m:

k+=1 is executed, it only changes the value in variable 
k</code, leaving variable <code>m
unaffected:

arr and arr2 are references to arrays located elsewhere in memory.

Hence, pushing a value results in the following transformation:

+------+
| arr  |------+
+------+      |   +-----------+
              +-->| (array )  |
+------+      |   +-----------+
| arr2 |------+   | length: 0 |
+------+          | 0: 1      |
                  +-----------+

Does this apply to all complex types?

Indeed, this behavior applies to all objects (including standard arrays which are objects in JavaScript) as well as new typed arrays.

The key concept to remember is that variables store values. When a variable points to an object or array, the stored value is a reference to the actual object/array, not a duplicate of it.

Understanding that object references are treated as values, similar to numbers, greatly aids in comprehending JavaScript code (as well as code in other languages that operate in a similar manner, such as Java).

Answer №2

Let's delve into why this phenomenon occurs:

Javascript categorizes values into two main types:

  1. Complex types
  2. Primitive types

An object is considered a complex type in Javascript, and examples include:

[]
{}
new String()
new Date()

In contrast, primitive types consist of:

'a string'
23
true

The reason for the difference lies in how referencing works for complex versus primitive types.

var aString = 'myString';
var refString = aString;

In the above scenario, "aString" is simply copied to refString, creating two independent values. However, when it comes to complex types:

var anArray = [];
var refArray = anArray;

var anObject = {};
var refObject = anObject;

Both variables reference the same array or object instance, rather than separate copies.

This concept also applies when checking for equality:

'my string' === 'my string' // true
23 === 23 // true
true === true // true

For complex types, Javascript doesn't compare memory references but rather value similarities:

{} === {} // false
[] === [] // false

var myObject = {};
var myObjectReferenced = myObject;
myObject === myObjectReferenced // true

Understanding this distinction is crucial in Javascript to avoid inadvertently altering shared objects thinking they are unique.

I hope this explanation clarifies things for you.

Answer №3

When it comes to array objects, they are interconnected through their pointer variables. Therefore, any changes made in one object will directly impact the other object as well.

Answer №4

In JavaScript, numbers are considered to be primitive data types, which means that the actual data is stored directly in the variables themselves.

var x = 5,
    y = x;

When assigning a value, such as in y = x, a copy of the value is created for each variable. Any changes made to one variable will not affect the other because they are independent copies.

On the contrary, arrays are treated as reference types in JavaScript.

var arr = [],
    arrCopy = arr;

When an array is assigned to another variable, like arrCopy = arr, it actually copies a reference to the original array. This means that any modifications made to the array through one variable will be reflected in the other variable as well.

Answer №5

In JavaScript (as well as in other programming languages), there exist two types of variables. The first type is known as "primitive" types, which include numbers, strings, and booleans. On the other hand, the second type is referred to as "reference" types, encompassing all other object types.

A helpful analogy is to envision primitive types as individual drawers, each containing a specific value. For instance, one drawer may hold the number 1, while another stores the string "John". When accessing a primitive type, you directly retrieve the value from its designated drawer.

Contrastingly, reference types do not actually store the value within the drawer itself. Instead, they hold instructions on how to locate the value in memory, which remains hidden. If you duplicate the contents of a "reference drawer" into another variable, you are duplicating the directions to access the value rather than the value itself. Consequently, both variables would point to the same underlying value.

The rationale behind this distinction involves efficient memory management within your program, optimizing resources effectively.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to divide an array of objects into three separate parts using JavaScript?

I am looking to arrange an array of objects in a specific order: The first set should include objects where the favorites array contains only one item. The second set should display objects where the favorites array is either undefined or empty. The third ...

Error: Unable to access the property '_locals' of an undefined value

I have been experimenting with nodejs on my Ubuntu 16.04 system, where I successfully installed Node and npm. However, I encountered an error stating "TypeError: Cannot read property '_locals' of undefined" while trying the following code: var e ...

Is there a way to retrieve the line number of an error within a dynamically inserted <script> element?

When I dynamically create a script element and add it to the page, the errors do not give me the line numbers of the script itself, but instead provide the line number where I append the script. The following code in a .js file will result in an error mes ...

What are some ways to incorporate inline TypeScript Annotations into standard JavaScript code?

If you're using VSCode, there's a new feature that allows you to implement type checking for traditional JavaScript files. There are instances where I wish to specify the type of a variable or parameters in a method or function to enhance auto-co ...

Tips for accessing information from a FOR loop within DIV tags

Let's explore the following code snippet: Here is the HTML generated: <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Website ...

Encountering a "Page Not Found" error while configuring Passport in Express 4

Struggling with integrating passport into my Node.js application. Despite rearranging my requirements in app.js, I'm unable to resolve the issue. The error message reads: Not Found 404 Error: Not Found at /home/salma/Desktop/my-project/app.js:5 ...

'The error thrown states: "ReferenceError: httpResponse is not defined" occurs while attempting to parse the JSON response from a Parse HTTP

My commitment statement involves sending multiple requests to eBay, each time using the properties of a matchCenterItem as parameters. Once all instances have been processed, I aim to transmit all the responses to my iOS application. However, my effort to ...

Troubleshooting: jQuery.load function not functioning properly within ASP.NET MVC

I'm facing an issue with my code setup. Currently, I have the following components in different files: @Html.Raw(File.ReadAllText(Server.MapPath("~/Views/Home/index.html"))) This is included in my Razor file. <li><a href="#">Personal Re ...

What is the best way to ensure a string of words in HTML/CSS wraps to the next line seamlessly?

As I work on creating my portfolio website using Bootstrap and custom CSS, I am running into an issue with the game titles breaking in the middle when displayed. Despite my limited proficiency in English, I tried searching for a solution without success. ...

Utilizing Angular to Toggle Visibility with Button Directives

Within my main view, I have three directives that each display different sets of data. <div> <sales-view></sales-view> </div> <div> <units-view></units-view> </div> Addi ...

Retrieve data from controller using jQuery Ajax

I am in need of assistance with my HTML form and controller interaction. I require a Boolean result from the controller based on user input. Here is an overview of my current form: <div id="temp"></div> @using (Html.BeginForm("Re ...

"Encountering a 404 error in a JQuery Ajax POST request when trying to send

Recently, I have been working with Adobe InDesign extensions and one of the tasks involves uploading an XML file to a server using a jQuery AJAX POST call. To achieve this, I need to read the XML file from the file system, store it in a variable, and then ...

Is there a way to retrieve the objects generated by DirectionsRenderer on Google Maps V3?

Is there a simple method to access the objects and properties of the markers and infowindows that are generated by the DirectionsRenderer? (such as the "A" and "B" endpoints of the route) I want to swap out the infowindows for the "A" & "B" markers wi ...

Incorporating an external TypeScript script into JavaScript

If I have a TypeScript file named test.ts containing the code below: private method(){ //some operations } How can I access the "method" function within a JavaScript file? ...

Ensure the appropriate TypeScript types are utilized for error middleware in Express

Struggling to properly define the types in my express application. I am encountering issues with my middleware error function and cannot seem to find a suitable example or get the correct types set up. Despite numerous attempts, here is my current version: ...

Load a page from a different domain using uframe

Looking for a solution to successfully load an external URI using uFrame. Currently encountering an "Access Denied" issue when attempting to do so on Firefox. Any suggestions? ...

Vue watchers capturing original value prior to any updates

When working with Vue.js, we can easily access the value after modification within watchers using the following syntax: watch: function(valueAfterModification){ // ...... } But what about getting the value before it's modified? PS: The official ...

The action of POSTing to the api/signup endpoint is

Currently delving into the MEAN stack, I have successfully created a signup api. However, when testing it using POSTMAN, I encountered an unexpected error stating that it cannot POST to api/signup. Here is a snapshot of the error: Error Screenshot This ...

The functionality of the TURF booleanwithin feature is malfunctioning and not producing the

Currently, I am working on validating whether a polygon is completely within another polygon. However, there are cases where more complex polygons should return false, but turf interprets them as valid. If you'd like to see the sandbox, click here: ...

Having trouble with the `click()` function not working on a button while using Selenium in

Currently, I am running a selenium test on a remote server in headless mode using the chrome driver. However, when trying to click on a button with the following step, the button does not get clicked. Below is the test step attempting to click the element ...