Tricky Parts of JavaScript I?-?Data Types vs Assignment & Equality Operators

Tricky Parts of JavaScript I?-?Data Types vs Assignment & Equality Operators

In the world of programming, JavaScript, like any language, has its fair share of tricky aspects that can stump developers. Whether you’re a seasoned pro or just starting out, these intricacies are bound to cross your path as you build web applications or tinker with server-side logic using Node.js. In this article and the next, we’ll explore some of these tricky elements.

So, let’s dive right?in.

1. Primitive vs. Reference Data Types and Assignment Behavior

In JavaScript, data types are broadly categorized into two classes: primitive data types, often referred to as “value data types,” and reference data types. These two categories exhibit distinct behaviors when it comes to assignment. Let’s delve into some examples to illuminate this concept:

// Example Set 1
let a = 5;
let b = a;
b = 10;

console.log(a); // Output: 5
console.log(b); // Output: 10

// Example Set 2
let str1 = "Hello";
let str2 = str1;
str2 += " World";

console.log(str1); // Output: "Hello"
console.log(str2); // Output: "Hello World"

// Example Set 3
let arr1 = [1, 2, 3];
let arr2 = arr1;
arr2.push(4);

console.log(arr1); // Output: [1, 2, 3, 4]
console.log(arr2); // Output: [1, 2, 3, 4]

// Example Set 4
let obj1 = { name: "Ivan" };
let obj2 = obj1;
obj2.name = "Esther";

console.log(obj1.name); // Output: "Esther"
console.log(obj2.name); // Output: "Esther"        

Example Sets 1 & 2?—?Primitive Values (Number and?String)

In these set of examples, we’re working with primitive values of the Number and String data types, which belong to the category of Primitive Data Types. JavaScript also includes other primitive data types, such as booleans, null, undefined, symbols, and BigInt.?

Let’s look at three characteristics of Primitive Data types which are essential to understanding the behaviors in these two set examples:?

  1. Direct Storage: Primitive values are stored directly in memory. What this means is that when you assign a primitive value to a variable, that variable holds the actual value directly in memory.
  2. Passed by Value: Primitive values are passed by value. What this means is that when you assign a primitive value to a another variable, a copy of the actual value is made. Modifying the copied value does not affect the original value.
  3. Immutable: Once a primitive value is created, it cannot be changed. Any operation that appears to modify a primitive value actually creates a new value.

In the example set 1,?

  • Variable a is assigned the primitive value 5 and a holds the value directly in memory.
  • When b is assigned the value of a using b = a, a copy of the actual primitive value in a (which is 5) is made and stored in b due to the passed by value property.
  • Subsequently, when b is reassigned the value of 10?, this change does not propagate back to a since each variable has its own independent copy of the value 5.
  • console.log(a); outputs 5 because the value of a remains unaffected by the subsequent assignment to b.
  • console.log(b); outputs 10 because b was assigned the value 10 after initially holding the value of a.

Similarly, with strings in example set 2,

  • Variables str1 and str2 initially hold distinct copies of the primitive value "Hello".
  • When you concatenate " World" to str2 using the += operator, it creates a new string(due to the immutability property) with the combined value and assigns it to str2.?
  • Importantly, this operation does not modify the original string value in str1, and the value in str1 remains unchanged.

Example Sets 3 & 4— Reference Types(Arrays and?Objects)

In these examples, we are dealing with Arrays and Objects which are Reference data types. Other examples are Functions and Classes. Here are some key characteristics of reference data types:

  1. Stored by Reference: When you create a variable and assign a reference data type to that variable, the variable effectively holds a reference or memory address to the location in memory where the data is stored.
  2. Passed by Reference: When you assign a reference data type to another variable, you are effectively passing or assigning the reference, not duplicating the data. As a result, any changes made through the new variable affects the original data.
  3. Mutable: Reference data types are mutable, meaning that you can modify their content after they are created. Changes made to the data through one reference affect all references pointing to the same data.

In example set 3,

  • Variables arr1 and arr2 hold a shared reference to the same array data.
  • When arr2 is modified by pushing the value 4 into it, this change directly affects the underlying data that both arr1 and arr2 point to.
  • As a result, the data within the array is altered, and both arr1 and arr2 yield the same updated array with the added value 4.

In example set 4,

  • Variables obj1 and obj2 similarly share a reference to the same object data.
  • The alteration of the name property in obj2 from "Ivan" to "Esther" impacts the underlying object that both variables reference.
  • Consequently, the change is reflected in both obj1 and obj2, and they both display the updated name property value, which is "Esther".

2. Equality Operators

JavaScript has two types of equality operators: == (loose equality) and ===(strict equality). These operators can be tricky, as they don’t always behave as one might expect, particularly when comparing different data types or values.

Let’s explore both and see how they can be tricky with some examples:

// Example Set 1
1 == '1';  // true (string '1' is coerced to a number for comparison)
0 == false;  // true (coerces boolean to number for comparison)
"0" == false;  // true (both are coerced to number 0)
null == undefined;  // true (both are considered equal in ==)

// Example Set 2
1 === '1';  // false (number is not equal to string)
0 === false;  // false (number is not equal to boolean)
"0" == false;  // false (string is not equal to boolean)
null === undefined;  // false (different data types)        

To understand these behaviors, let’s dive deeper into each operator type:

Loose Equality?(==):?

The loose equality operator compares values while allowing type coercion, meaning it attempts to convert the values into a common type before making the comparison. This can lead to unexpected results, making it generally advisable to avoid its use.

In the first example set, the operands are coerced to the same data type before the comparison, hence returning true for all comparisons.

Strict Equality?(===):

The strict equality operator, on the other hand, compares values for equality without performing type coercion. It checks not only the value but also the data type. This typically leads to more predictable results.?

In the second example set, the operands aren’t coerced, and their data types are explicitly considered, leading to false results for all comparisons.

Note: Comparing Reference Data?Types

When comparing reference data types, such as arrays and objects, JavaScript’s equality operators check if the references point to the same data in memory, not if their content is the same.

//Will Return False
const arr1 = [1, 2, 3];
const arr2 = [1, 2, 3];
arr1 == arr2; // false (arrays are compared by reference, not by content)
arr1 === arr2; // false (for the same reason as above)

const obj1 = { key: "value" };
const obj2 = { key: "value" };
obj1 == obj2; // false (objects are compared by reference, not by content)
obj1 === obj2; // false (for the same reason as above)

//Will Return True
const arr1 = [1, 2, 3];
const arr2 = arr1; // arr2 reference the same array as arr1
arr1 == arr2; // true (both variables reference the same array)
arr1 === arr2; // true (for the same reason as above)

const obj1 = { key: "value" };
const obj2 = obj1; // obj2 reference the same object as obj1
obj1 == obj2; // true (both variables reference the same object)
obj1 === obj2; // true (for the same reason as above)        

For comparing the content of reference data types, you’ll usually need to iterate through their properties or elements to check for equality. Alternatively, you can serialize objects to JSON strings with JSON.Stringify( ) and compare those strings, or use libraries like lodash or Underscore.js, which offer the isEqual( ) utility function for such comparisons.


In Summary,

In this article, we uncovered some intricacies of primitive and reference data types and their corresponding behaviors with respect to assignment operators. We’ve also delved into the nuances of equality operators and how they can lead to unexpected results.

But our journey is far from over! Stay tuned for the next article where we’ll dive into scope and hoisting, shedding light on how hoisting can sometimes lead to surprising behavior. Additionally, we’ll explore the immutability of variables created with const and how it can affect your code.


要查看或添加评论,请登录

Theodora Gyambrah的更多文章

  • SQL vs NoSQL Databases?-?Part?2

    SQL vs NoSQL Databases?-?Part?2

    In our previous article, we explored databases, which are organized collections of data that are structured to enable…

  • SQL vs NoSQL Databases - Part 1

    SQL vs NoSQL Databases - Part 1

    Databases are organized collections of data that are structured to enable efficient storage, retrieval, and…

  • Tricky Parts of JavaScript II?-?Scoping, Hoisting & `const`?Keyword

    Tricky Parts of JavaScript II?-?Scoping, Hoisting & `const`?Keyword

    This is the sequel to a previous article which we tackled the intricacies of the various data types and their behavior…

    2 条评论
  • Programming Principles III: Writing SOLID code

    Programming Principles III: Writing SOLID code

    Looking back on our journey, we've delved into a diverse collection of programming principles. From KISS, DRY, YAGNI…

  • Programming Principles II: Going Beyond the Basics

    Programming Principles II: Going Beyond the Basics

    In our previous article, we delved into fundamental programming principles and practices, including KISS, YAGNI, DRY…

    3 条评论
  • Programming Principles I: The Basics

    Programming Principles I: The Basics

    In the field of software engineering, collaboration on codebases is a regular and integral part of our work. To ensure…

  • My Tech Journal - Part 3

    My Tech Journal - Part 3

    Earlier this year, I had a meeting with my mentor, Frederick Obeng-Nyarko , to talk about my career goals for the…

    2 条评论
  • Why the Hype About React, Vue and Angular? – Part 2

    Why the Hype About React, Vue and Angular? – Part 2

    This is the sequel to an initial article that aimed to shed light on the reasons fueling the hype around React, Vue…

  • Why the Hype About React, Vue, and Angular? – Part 1

    Why the Hype About React, Vue, and Angular? – Part 1

    Introduction Entering the world of tech as a web developer, you'll quickly notice a recurring theme: job postings and…

    6 条评论

社区洞察

其他会员也浏览了