about
Bits JavaScript Data
08/01/2024
Bits Repo Code Bits Repo Docs

Bits: JavaScript Data Types

types, initialization, and construction

0

Synopsis:

This page demonstrates simple uses of the most important JavaScript types. The purpose is to quickly acquire some familiarity with types and their uses.
  • JavaScript provides only dynamic reference types.
  • Creation of a dynamic type creates a handle that points to an instance in the managed heap.
  • Assignment of dynamic types assigns handles to instances on the managed heap, resulting in two handles to the same instance.
  • A variable bound to a JavaScript instance can be rebound, at run-time, to an instance of any other dynamic type.
JavaScript Types Details  Types are defined by the size of their memory allocations, the encodings used to place values in memory, and rules that define how the values can be accessed, modified, and combined. The name of an instance of any JavaScript type binds to a unique handle that refers to a heap allocation that may have other handles referring to it.

Table 1.0 JavaScript Types

Type Comment Example
-- Primitive reference types ----
Number ints and floats -53, 3.14159, 1.333e+8
BigInt arbitrarily large integer up to capacity of memory 34567898765432101234567
String immutable sequence of chars
change creates new String object
s = "a string";
Boolean exactly two values, true and false bool b = true;
Symbol unique value which may be used as key for object structures const sym1 = Symbol('prop1');
Undefined value given to unintialized variable let sym1;   // value is undefined
Null intentional no value let i = null;
-- Object reference types ----
Object Structure with hashed (key, value) elements let o = Object();
o.name = "Jim"
o.show = function () {
  document.write("name = ", o.name);
}
Function Object with reference to code in static memory so it can be executed function f(a) {
  /* executes using a */
}
Array sequential resizeable indexed collection of arbitrary elements let a = [1, 3, 2, -5]
let b = new Array(1, "three", 2);
Date holds a timestamp equal to number of milliseconds since January 1, 1970, UTC, and provides methods to access current local time and UTC, and set timestamps let dt = Date();
let day_of_week = dt.getDay();
RegExp holds state machine that matches an input string to a specified pattern
Regular Expressions Reference
const text = "first line\nsecond line\r\nlast line";
let lines = text.split(/\r\n|\r|\n); // split accepts RegEx
Error Error objects are thrown when runtime error occurs.
Error subtypes:
EvalError, RangeError, Reference Error, SyntaxError, TypeError, URIError, AggregateError, InternalError,
throw new Error("some message");
Many additional JavaScript defined types: Map, Set, Int32Array, DataView, Atomics, ..., Math, ...,
-- User-defined Types --
User-defined types Based on classes, these will be discussed in the next Bit.
JavaScript Type Attributes 

Table 2. JavaScript Type System Attributes

Dynamic typing JavaScript types are dynamic. All names bind to any type, types are evaluated at run-time, and names may be rebound to any type of data. All data is held in the JavaScript managed heap.
Type inference Compiler infers all types from the declaring definition at load or run-time.
Duck typing All expressions are checked at run-time. Exceptions are thrown at load-time if there are any failures of syntax. An exception is thrown at run-time if an expression cannot be evaluated.
Generics There are no generics in JavaScript code since any type can be passed to a function or added to a collection. The JavaScript interpreter checks the validity of operations on data and throws exceptions if expressions are invalid.

1.0 JavaScript Types

All JavaScript data is located in the host's managed heap. Varibles hold handles to that data. Assignment and construction of numbers and arrays copies the source object's handle, not its instance, so that results in two handles pointing to the same instance. JavaScript strings are immutable, so any change will create a new object. All the other types illustrated here, numbers and arrays, are mutable

1.1 Demonstration Code

JavaScript needs a host to load and execute. In this demo we use a simple web page With a head element holding all of the JavaScript definitions, a body element that holds a placeholder div element where a title will be rendered, using the function heading(), and a script element with function invocations for the heading and demonstrations. Styles and JavaScript in the head are parsed and tokenized. JavaScript in the body is executed as it is encountered during loading. The panels, below, contain demonstration code in the left and output in the right. The output has been placed so that it is adjacent to the code that generates it. The panels are seperated by a "splitter bar" that can be dragged to the left or right to see any content that may not be visible after loading. You can accomplish the same thing by clicking in either panel to increase its width.
<!DOCTYPE html>>
<html>
<!--
  Js_Data.html

  JavaScript types:
    Number, BigInt, String, Boolean,
    null, undefined,
    Object, Symbol

-->
<head>
  <script>
    var nl = "<br />";
    var nil = "";

    /* Demonstration starts here */
    function heading() {
            document.getElementById("data").innerHTML = 
              "<h2>Javascript Data</h2>";
    }
    function execute() {
      showNote("Demo numbers")

      println("-- let t1 = 42 --");
      let t1 = 42;
      showType(t1, "t1");
      println(nil);

      println("-- let t2 = t1 --");
      let t2 = t1;
      isSameObject(t2, "t2", t1, "t1");
      println(nil);

      println(
        "-- let t2 = 3.1415927 -- : change of object"
      );
      t2 = 3.1415927;
      isSameObject(t2, "t2", t1, "t1");
      print(nl);
      showType(t1, "t1");
      showType(t2, "t2");
      println(nil);

      showNote("Demo strings");

      println("-- let t3 = \"a string\" --");
      let t3 = "a string";
      showType(t3, "t3");
      print(nl);

      println("-- let t4 = t3 --");
      let t4 = t3;
      isSameObject(t4, "t4", t3, "t3");
      println(nil);
      showType(t3, "t3");
      showType(t4, "t4");
      print(nl);

      println(
        "-- t4 += " + 
        "\" and another string\" -- : copy on write"
      );
      t4 += " and another string";
      isSameObject(t4, "t4", t3, "t3");
      println(nil);
      showType(t3, "t3");
      showType(t4, "t4");
      print(nl);

      showNote("Demo arrays");
      println("--- t5 = [1, 2, 3] ---");

      let t5 = [1, 2, 3];
      showType(t5, "t5");
      print(nl);

      println("--- let t6 = t5 ---");
      let t6 = t5;
      isSameObject(t6, "t6", t5, "t5");
      println(nil);
      showType(t5, "t5");
      showType(t6, "t6");
      print(nl);

      println("--- t6[1] = -2 --- : no copy on write");
      t6[1] = -2;
      isSameObject(t6, "t6", t5, "t5");
      println(nil);
      showType(t5, "t5");
      showType(t6, "t6");
      showNote("Source t5 modified!")
    }

    /*----------------------------------------------------- 
      display and analysis functions elided, see below
    */

  </script>
  <style>
    body {
      font-family:'Comic Sans MS', Tahoma;
      padding:2em;
    }
  </style>
</head>
<body>
  <div id="data"></div>
  <script>
    heading();
    execute();
  </script>
</body>
</html>


















Javascript Data
-------------------------
Demo numbers
-------------------------
-- let t1 = 42 --
t1, number
size: 8, value: 42

-- let t2 = t1 --
t2 is same object as t1

-- let t2 = 3.1415927 -- : change of object
t2 is not same object as t1

t1, number
size: 8, value: 42
t2, number
size: 8, value: 3.1415927

-------------------------
Demo strings
-------------------------
-- let t3 = "a string" --
t3, string
size: 16, value: a string

-- let t4 = t3 --
t4 is same object as t3

t3, string
size: 16, value: a string
t4, string
size: 16, value: a string

-- t4 += " and another string" -- : copy on write
t4 is not same object as t3

t3, string
size: 16, value: a string
t4, string
size: 54, value: a string and another string

-------------------------
Demo arrays
-------------------------
--- t5 = [1, 2, 3] ---
t5, object
size: 24, value: 1,2,3

--- let t6 = t5 ---
t6 is same object as t5

t5, object
size: 24, value: 1,2,3
t6, object
size: 24, value: 1,2,3

--- t6[1] = -2 --- : no copy on write
t6 is same object as t5

t5, object
size: 24, value: 1,-2,3
t6, object
size: 24, value: 1,-2,3
-------------------------
Source t5 modified!
-------------------------





























1.2 Display and Analysis Functions

JavaScript does not directly support generics so functions can be used for more than one type without a lot of code scaffolding as in C++, Rust, and C#. That makes the code much simpler, but now the developer must insure valid method arguments without the help of compiler diagnostics. For quick small prototypes, that works well. For large code bases, getting to valid argments requires careful implementation with a lot of trial and error. All of the functions used in this file to enhance output displays are discussed in the dropdown, below.
Display & Analysis
  /* analysis and display functions */

  function print(str) {
    document.write(str);
  }
  function println(str) {
    document.write(str + "<br />");
  }
  function showNote(text) {
    println("-------------------------");
    println(text);
    println("-------------------------");
  }
  /* Analysis functions */
  function showType(t, nm) {
    println(nm + ", " + typeof t);
    print("size: " + sizeof(t) + ", value: " + t);
    println(nil);
  }
  function isSameObject(o1, nm1, o2, nm2) {
    if (o1 === o2) {
      println(nm1 + " is same object as " + nm2)
    }
    else {
      println(nm1 + " is not same object as " + nm2)
    }
  }
  // https://gist.github.com/pgpbpadilla/10344038
  function sizeof(object) {
    var objectList = [],
      stack = [ object ],
      bytes = 0,
      value,
      i;

    while (stack.length) {
      value = stack.pop();

      if (typeof value === 'boolean') {
        bytes += 4;
      } else if (typeof value === 'string') {
        bytes += value.length * 2;
      } else if (typeof value === 'number') {
        bytes += 8;
      } else if (typeof value === 'object'
          && objectList.indexOf(value) === -1) {
        objectList.push(value);

        for (i in value) {
          if (value.hasOwnProperty(i)) {
            stack.push(value[i]);
          }
        }
      }
    }
    return bytes;
  }

Display:

The functions "print(str)", "println(str)", and "showNote(text)" are used to enhance the demonstration output and are simple enought to be self-explanitory.

Analysis:

"showType(t, nm)" accepts an object t and name string nm. It displays the name and type of t as evaluated by the interpreter, followed by its size and value. Size is computed with the sizeof(object) function discussed below and value is interpreted by document.write(t). The function "sizeof(object)" iterates recursively through the object's properties, accumulating the size of each, using an array with stack operations to traverse the object's tree.

2.0 Build

local machine

C:\github\JimFawcett\Bits\Javascript\Js_Data
> start firefox C:\github\JimFawcett\Bits\Javascript\Js_Data\Js_Data.html
C:\github\JimFawcett\Bits\Javascript\Js_Data
>

github site

clone Bits repository and double click on Js_Data.html

3.0 VS Code View

The code for this demo is available in github.com/JimFawcett/Bits. If you click on the Code dropdown you can clone the repository of all code for these demos to your local drive. Then, it is easy to bring up any example, in any of the languages, in VS Code. Here, we do that for JavaScript\Js_Objects. Figure 1. VS Code IDE - JavaScript Data Figure 2. Debugging JavaScript Data

4.0 References

Reference Description
JavaScript Tutorial - w3schools Interactive examples
JavaScript Data Types - javascript.info Summary with examples
JavaScript Reference - MDN Informal syntax reference