© Sammie Bae 2019
Sammie BaeJavaScript Data Structures and Algorithmshttps://doi.org/10.1007/978-1-4842-3988-9_2

2. JavaScript: Unique Parts

Sammie Bae1 
(1)
Hamilton, ON, Canada
 

This chapter will briefly discuss some exceptions and cases of JavaScript’s syntax and behavior. As a dynamic and interpreted programming language, its syntax is different from that of traditional object-oriented programming languages. These concepts are fundamental to JavaScript and will help you to develop a better understanding of the process of designing algorithms in JavaScript.

JavaScript Scope

The scope is what defines the access to JavaScript variables. In JavaScript, variables can belong to the global scope or to the local scope. Global variables are variables that belong in the global scope and are accessible from anywhere in the program.

Global Declaration: Global Scope

In JavaScript, variables can be declared without using any operators. Here’s an example:
1  test = "sss";
2  console.log(test); // prints "sss"

However, this creates a global variable, and this is one of the worst practices in JavaScript. Avoid doing this at all costs. Always use var or let to declare variables. Finally, when declaring variables that won’t be modified, use const.

Declaration with var: Functional Scope

In JavaScript, var is one keyword used to declare variables. These variable declarations “float” all the way to the top. This is known as variable hoisting. Variables declared at the bottom of the script will not be the last thing executed in a JavaScript program during runtime.

Here’s an example:
1  function scope1(){
2          var top = "top";
3          bottom = "bottom";
4          console.log(bottom);
5
6          var bottom;
7  }
8  scope1(); // prints "bottom" - no error
How does this work? The previous is the same as writing the following:
1  function scope1(){
2          var top = "top";
3          var  bottom;
4          bottom = "bottom"
5          console.log(bottom);
6  }
7  scope1(); // prints "bottom" - no error

The bottom variable declaration, which was at the last line in the function, is floated to the top, and logging the variable works.

The key thing to note about the var keyword is that the scope of the variable is the closest function scope. What does this mean?

In the following code, the scope2 function is the function scope closest to the print variable:
1  function scope2(print){
2          if(print){
3                   var insideIf = '12';
4          }
5          console.log(insideIf);
6  }
7  scope2(true); // prints '12' - no error
To illustrate, the preceding function is equivalent to the following:
1  function scope2(print){
2          var insideIf;
3
4          if(print){
5                   insideIf = '12';
6          }
7          console.log(insideIf);
8  }
9  scope2(true); // prints '12' - no error

In Java, this syntax would have thrown an error because the insideIf variable is generally available only in that if statement block and not outside it.

Here’s another example:
1  var a = 1;
2  function four() {
3    if (true) {
4      var a = 4;
5    }
6
7    console.log(a); // prints '4'
8  }

4 was printed, not the global value of 1, because it was redeclared and available in that scope.

Declaration with let: Block Scope

Another keyword that can be used to declare a variable is let. Any variables declared this way are in the closest block scope (meaning within the {} they were declared in).
1  function scope3(print){
2          if(print){
3                   let insideIf = '12';
4          }
5          console.log(insideIf);
6  }
7  scope3(true); // prints ''

In this example, nothing is logged to the console because the insideIf variable is available only inside the if statement block.

Equality and Types

JavaScript has different data types than in traditional languages such as Java. Let’s explore how this impacts things such as equality comparison.

Variable Types

In JavaScript, there are seven primitive data types: boolean, number, string, undefined, object, function, and symbol (symbol won’t be discussed). One thing that stands out here is that undefined is a primitive value that is assigned to a variable that has just been declared. typeof is the primitive operator used to return the type of a variable.
 1  var is20 = false; // boolean
 2  typeof is20; // boolean
 3
 4  var  age = 19;
 5  typeof age; // number
 6
 7  var  lastName = "Bae";
 8  typeof lastName; // string
 9
10  var fruits = ["Apple", "Banana", "Kiwi"];
11  typeof fruits; // object
12
13  var me = {firstName:"Sammie", lastName:"Bae"};
14  typeof me; // object
15
16  var nullVar = null;
17  typeof nullVar; // object
18
19  var function1 = function(){
20          console.log(1);
21  }
22  typeof function1 // function
23
24  var blank;
25  typeof blank; // undefined

Truthy/Falsey Check

True/false checking is used in if statements. In many languages, the parameter inside the if() function must be a boolean type. However, JavaScript (and other dynamically typed languages) is more flexible with this. Here’s an example:
1  if(node){
2          ...
3  }

Here, node is some variable. If that variable is empty, null, or undefined, it will be evaluated as false.

Here are commonly used expressions that evaluate to false:
  • false

  • 0

  • Empty strings ('' and "")

  • NaN

  • undefined

  • null

Here are commonly used expressions that evaluate to true:
  • true

  • Any number other than 0

  • Non-empty strings

  • Non-empty object

Here’s an example:
1  var printIfTrue = ";
2
3  if (printIfTrue) {
4          console.log('truthy');
5  } else {
6          console.log('falsey'); // prints 'falsey'
7  }

=== vs ==

JavaScript is a scripting language, and variables are not assigned a type during declaration. Instead, types are interpreted as the code runs.

Hence, === is used to check equality more strictly than ==. === checks for both the type and the value, while == checks only for the value.
1  "5" == 5 // returns true
2  "5" === 5 // returns false

"5" == 5 returns true because "5" is coerced to a number before the comparison. On the other hand, "5" === 5 returns false because the type of "5" is a string, while 5 is a number.

Objects

Most strongly typed languages such as Java use isEquals() to check whether two objects are the same. You may be tempted to simply use the == operator to check whether two objects are the same in JavaScript.

However, this will not evaluate to true.
1  var o1 = {};
2  var o2 = {};
3
4  o1 == o2 // returns false
5  o1 === o2 // returns false

Although these objects are equivalent (same properties and values), they are not equal. Namely, the variables have different addresses in memory.

This is why most JavaScript applications use utility libraries such as lodash1 or underscore,2 which have the isEqual(object1, object2) function to check two objects or values strictly. This occurs via implementation of some property-based equality checking where each property of the object is compared.

In this example, each property is compared to achieve an accurate object equality result.
 1  function isEquivalent(a, b) {
 2      // arrays of property names
 3      var aProps = Object.getOwnPropertyNames(a);
 4      var bProps = Object.getOwnPropertyNames(b);
 5
 6      // If their property lengths are different, they're different objects
 7      if (aProps.length != bProps.length) {
 8          return false;
 9      }
10
11      for (var  i = 0; i < aProps.length; i++) {
12          var propName = aProps[i];
13
14          // If the values of the property are different, not equal
15          if (a[propName] !== b[propName]) {
16              return false;
17          }
18      }
19
20     // If everything matched, correct
21     return  true;
22  }
23  isEquivalent({'hi':12},{'hi':12}); // returns true
However, this would still work for objects that have only a string or a number as the property.
1  var obj1 = {'prop1': 'test','prop2': function (){} };
2  var obj2 = {'prop1': 'test','prop2': function (){} };
3
4  isEquivalent(obj1,obj2); // returns false
This is because functions and arrays cannot simply use the == operator to check for equality.
1  var function1 = function(){console.log(2)};
2  var function2 = function(){console.log(2)};
3  console.log(function1 == function2); // prints 'false'

Although the two functions perform the same operation, the functions have different addresses in memory, and therefore the equality operator returns false. The primitive equality check operators, == and ===, can be used only for strings and numbers. To implement an equivalence check for objects, each property in the object needs to be checked.

Summary

JavaScript has a different variable declaration technique than most programming languages. var declares the variable within the function scope, let declares the variable in the block scope, and variables can be declared without any operator in the global scope; however, global scope should be avoided at all times. For type checking, typeof should be used to validate the expected type. Finally, for equality checks, use == to check the value, and use === to check for the type as well as the value. However, use these only on non-object types such as numbers, strings, and booleans.