Saturday, November 23, 2019

JavaScript Data Types

1 Introduction

JavaScript types can be divided into two categories: primitive types and object types.

JavaScript Data Types
Primitive Types
Object Types
  • string
  • number
  • boolean
  • null
  • undefined
  • symbol
  • bigint
fundamental Object types
specialized Object types
  • Object
  • Array
  • Function
  • Error
  • Date
  • RegExp
  • Class
  • Set
  • Map

2 Checking the type of a value

The typeof operator let you determine the type of a value stored in a variable.

/* primitive types */

console.log(typeof "hey, you");     //"string", OK
console.log(typeof 95);             //"number", OK
console.log(typeof true);           //"boolean", OK
console.log(typeof null);           //"object" instead of "null"!
console.log(typeof undefined);      //"undefined", OK  
      
/* object types */

console.log(typeof {});             //"object", OK
console.log(typeof []);             //"object", OK 
console.log(typeof function(){});   //"function" instead of "object"!

console.log(typeof new Date());     //"object", OK
console.log(typeof /^Hello JS$/);   //"object", OK 
console.log(typeof new Error());    //"object", OK

Since the typeof operator returns "object" for all objects except function objects, you can only determine whether a value is an object or a primitive type. To distinguish a class of object from another, you have to use the instanceof operator, the class attribute or the constructor property.

3 The Number Type

In JavaScript all numbers (whether integers or floating points) are represented as 64-bit floating-point values. The 64-bit floating-point IEEE 754 standard, can represent numbers as large as ±1.7976931348623157 × 10308 and as small as ±5 × 10−324.

The JavaScript number format allows you to exactly represent all integers between −9007199254740992 (or −253)) and 9007199254740992 (or 253), inclusive. If you use integer values larger than this, you lose precision in the trailing digits.

Real numbers are infinitely many, this means that, when working with real numbers in JavaScript, the representation of the number is an approximation of the actual number.

Binary floating-point representations cannot exactly represent numbers like 0.1.

((.3 - .2) == .1) == false // (.3 - .2) is not equal to .1
((.2 - .1) == .1) == true  // (.2 - .1) is equal to .1

To perform important financial calculations it's good practice to manipulate monetary values as integer cents rather than fractional euros.

4 The String Type

The JavaScript String type represents sequence of characters, text data

  • a string value is an immutable sequence of Unicode characters
  • JavaScript does not have a type to hold a single character
  • both string and array types are sequences of values and use indexes starting from zero
Unicode encoding and string length
  • a character set encodes characters by assigning a number, or code point, to characters
  • JavaScript uses Unicode UTF-16, the Unicode character set with encoding number 16 bit large.
    • the characters of the most used alphabets have code point that fits in 16 bits
    • the characters of other alphabets have code point that use two 16-bit values
  • the String length property is the number 16 bits values it contains, not the characters. A JavaScript string of length 2 might represent a string formed by only a single Unicode character.
// You can represent letters as regular ASCII character or as UTF code.

// JavaScript uses a sequence of six ASCII characters to specify any 16-bit Unicode code point.
// For example, to represent the latin small letter é with acute accent, 
// specify four hexadecimal digits 0x00E9 or the unicode value "\u00E9"
      
var ascii = 'café';
var utf8  = 'caf\u00E9';
    
console.log(ascii); // "café"
console.log(utf8);  // "café"

utf-8 16 bits values vs characters

  • the JavaScript string methods operate on 16-bit values, not on characters.
  • strings are iterable, the the for/of loop iterates over characters not values
String Literals

A string literal is a sequence of characters enclosed in single or double quotes; they are also known as single-quoted string literals and double-quoted string literals

Example: string literals between quotes

''  // empty string

'single quoted string'
"double quoted string"

// simple quoted string holding double-quote characters
'<p class="para"> text content </p>'

// simple quoted string must escape apostrophe
'I crashed my father\'s car'

Backtick string literals

  • in ES6, string literals can also be enclosed in backticks
  • backtick string literals are known as ES6 template literals or template strings
  • backtick string literals have a special syntax that allows to embed expressions
Working with strings

String comparison

  • strings are compared for equality and inequality by the operators === and !==
  • strings are compared for relationship by relational operator <, <=, > and >=.
  • string comparison is performed by comparing 16-bit values
var ascii = 'café';
var utf8 = 'caf\u00E9';
console.log(ascii === utf8); // true  

var string1 = 'AAA';
var string2 = 'aaa';
console.log(string1 === string2); // false
console.log(string1 < string2); // true

String Value and String Object

// String value creation
var string_value = "hello world";
console.log(typeof string_value); //"string"
console.log(string_value instanceof String); // false

// String object creation
var string_object = new String("hello world"); 
console.log(typeof string_object);   // "object"
console.log(string_object instanceof String); // true

Character access

var hail = "hello world"; 
console.log(hail.charAt(0));             // "h"
console.log(hail.charAt(hail.length-1)); // "d"
        
// string as read-only array
console.log(hail[0]);              // "h"
console.log(hail[hail.length-1]);  // "d" 
        
// get the UTF-8 code for 16 bits code point
console.log(hail.charCodeAt(0));      // 104
// get the UTF-8 code for code point larger than 16 bits
console.log(hail.codePointAt(0));     // 104

Adding strings

var half_hail = "hello";
        
// do not use the concat method.
console.log(half_hail.concat(" ","world")); // "hello world"
// the + operator performs better than the concat method
console.log(half_hail + " " + "world"); // "hello world"

Getting a substring

// slice() and substring() are methods for creating primitive string values from a substrings. 
// These methods accept two arguments:
// - the first argument is the position where to start capture of a substring, 
// - the second optional argument indicates where to stop capture 
                
var hail = "hello world";
console.log(hail.slice(3));        //"lo world", substring from position 3 to end.
console.log(hail.substring(3));    //"lo world", substring from position 3 to end.
                
console.log(hail.slice(3, 7));     //"lo w", substring from position 3 included to 7 excluded.
console.log(hail.substring(3,7));  //"lo w", substring from position 3 included to 7 excluded.

Position searching

// indexOf() and lastIndexOf() methods locate substrings within a given string.
// parameters:
//    - first parameter is the substring to be searched
//    - second optional parameter is the position number where to start search the substring 
// return:
//    - the position of the substring or -1 if the substring isn't found.
        
var hail_string = "hello world";
hail_string.indexOf("l") // 2, find the first occurrence of 'l' character and begin looking for it at the begin of the string
hail_string.lastIndexOf("l") // 9, find the first occurrence of 'l' character and begin looking for it at the end of the string   
            
hail_string.indexOf("l", 6) // 9, find the first occurrence of 'l' character, starting search at position 6.
hail_string.lastIndexOf("l", 6) // 3, find the last occurrence of 'l' character, stopping search at position 6

Boolean searching

// startsWith(), endsWith() and includes() methods determine if a given string contain a substring at a given position 
// parameters:
//    - first parameter is the substring to be searched
// return:
//    - true or false, if the substring is found or not

var hail_string = "hello world";
console.log(hail_string.startsWith("hell"));    // true
console.log(hail_string.endsWith("dd"));        // false
console.log(hail_string.includes("o w"));       // true

String modification

var hail = "hello world";
        
// Creating modified versions of a string
console.log(hail.replace("hello", "bye bye"));  // "bye bye world"
console.log(hail.toLowerCase());         // => "hello, world"
console.log(hail.toUpperCase());         // => "HELLO, WORLD"

String Normalization

var hail = "hello world";
        
// normalize Unicode strings to Composed forms
console.log(hail.normalize());  // hello world
        
// normalize Unicode strings to Decomposed forms         
console.log(hail.normalize("NFD"));  // hello world     

Padding, Trimming and Repeating strings

// adding characters to a string 
console.log("x".padStart(3));         // "  x"
console.log("x".padEnd(3));           // "x  "
console.log("x".padStart(3, "+"));    // "++x"
console.log("x".padEnd(3, "-"));      // "x--"
                
// trimming characters from a string
var text = " SOME TEXT ";
console.log(text.trim());         // "SOME TEXT"
console.log(text.trimStart());    // "SOME TEXT "
console.log(text.trimEnd());      // " SOME TEXT"
        
// repeating a string
var text = "text ";
console.log(text.repeat(4));      // "text text text text "

Converting strings to Arrays

const words = 'word_1 word_2 word_3';
const arrayOfWords = words.split(' ');
console.log(arrayOfWords); // ["word_1", "word_2", "word_3"]
        
const chars = 'string of chars';
const arrayOfChars = chars.split('');
console.log(arrayOfChars); // ["s", "t", "r", "i", "n", "g", " ", "o", "f", " ", "c", "h", "a", "r", "s"]
Template Literals

ES6's template literals allows the creation on multiline strings

let string = `multiline
    text`;

ES6's template literals can use placeholders to embed expressions

  • a placeholder is a dollar symbol and two curly braces encapsulating an expression: (${expression})
  • the value of the expression is converted to string and embedded in the template literal

Example: template literals and string substitution

// variable substitution
let name = 'Michael'; 
`welcome to my blog ${name}` // "welcome to my blog Michael"

// expression substitutions
let str = `one divided by two is ${1/2}`;
console.log(str);  // one divided by two is 0.5

Example: template literals and ternary operator

// ES5 ternary operator with quoted strings
const greetingWithQuotes = (love) => {
  return 'Hello ' + (love ? "World" : "JavaScript") + '!';
}
// ES6 ternary operator with template strings
const greetingWithTicks = (love) => {
      return `Hello ${love ? "World" : "JavaScript"}!`;
}
console.log(greetingWithQuotes(true));  // Hello World!
console.log(greetingWithTicks(false));  // Hello JavaScript!

Example: template literals and method calls

let user = {firstName: 'Mick', lastName: 'Doohan'};
`welcome to my blog ${user.firstName.toUpperCase()}` // "welcome to my blog MICK"

Example: template literals with loops

// template literals to substitute variable of forEach iteration 
const dogs = [ "Kiki", "Lara", "Molly", "Milo" ];
var list = '';
dogs.forEach( item => { list += `<li> ${item} </li>`; } );
list = `<ul> ${list} </ul>`;
console.log(list); // <ul> <li> Kiki </li><li> Lara </li><li> Molly </li><li> Milo </li> </ul>

Example: nesting templates

// substitute variable of map iteration and the result value of array joining
const dogsAge = [ { name: 'Kiki', age: 2 }, { name: 'Lara', age: 8 }, { name: 'Molly', age: 1 } ];
var list = `<ul> ${ dogsAge.map( dog => `<li> ${dog.name} is ${dog.age} </li>` ).join('') } </ul>`;
console.log(list); // <ul> <li> Kiki is 2 </li> <li> Lara is 8 </li> <li> Molly is 1 </li> </ul>

5 The Boolean Type

The boolean type contains two values represented by the two keywords true and false.

6 null and undefined

null is a language keyword that evaluates to a special value that is used to indicate the absence of a value. In practice, null is used to indicate “no value” for numbers and strings as well as objects.

undefined is another value to indicate absence. It is the value of variables that have not been initialized and the value you get when you query the value of an object property or array element that does not exist. The undefined value is also returned by functions that have no return value, and the value of function parameters for which no argument is supplied.

null VS undefined

null
undefined
definition language keyword predefined global variable
meaning absence of a value absence of a value
convert to boolean value false false
typeof operator returns “object” “undefined”
use a program-level expecxted absence of value


Example:
  • value assigned to numbers, strings and objects to indicate “no value
  • value passed to function to indicate “no value
a system-level unexpecxted absence of value


Example:
  • value of not initialized variables
  • value of object properties or array elements that do not exist
  • value returned by function that do not return a value
  • value of function parameters for which no argument is supplied

7 The Symbol Type

Which data types to use for object property names?

  • Until ECMAScript 5, object's property names could only be strings.
  • ECMAScript 6 introduces the Symbol type for defining object property name as alternative to the string type

Creating a Symbol value

  • get a Symbol value by invoking the Symbol() constructor function
  • the Symbol() function takes an optional string as argument and return an unique Symbol value
// the optional string parameter appears in the output of the toString() method
let mySymbol = Symbol('label');
console.log(mySymbol.toString()); // "Symbol(label)"

Why using Symbolic names as property names?

  • the Symbol() function never returns the same value twice, even when invoked with the same argument
  • if anyone adds a new property to a shared object, using a symbolic property name, he can be sure that he is not going to overwrite an existing property with the same name.

What is the use of a Symbol value?

  • create a Symbol value and keep it private to make sure that your property will never conflict with properties used by other JS libraries
  • create a Symbol value and allow public access to it, if you are creating an utility function that you wish other people to use.

How to share a Symbol value?

  • JavaScript defines the Symbol.for() function as global Symbol registry.
  • the Symbol.for() function takes a string argument and returns the Symbol value that is associated with the passed string argument:
    • if a symbol is not yet associated with that string, the Symbol.for() creates a new Symbol and return it.
    • if a symbol is already associated with that string, the Symbol.for() returns the existing Symbol.
  • when invoked with the same argument Symbol.for() returns the same symbol value, while Symbol() returns a always a new symbol value.
// Symbol() function always creates a new Symbol value
let privateSym  = Symbol('label');
let privateSym2 = Symbol('label');
console.log(privateSym === privateSym2);  // false

// Symbol.for() static method is the Symbol registry
let sharedSym  = Symbol.for('label');
let sharedSym2 = Symbol.for('label');
console.log(sharedSym === sharedSym2);  // true     

// The Symbol.for() static method retrieves the symbol key
// from the symbol registry for a given shared symbol 
console.log(Symbol.keyFor(sharedSym));  // "label"
console.log(Symbol.keyFor(privateSym)); // undefined

8 The Global Object

The global object is a regular JavaScript object that defines global functionalities that are available to any JavaScript program. (https://developer.mozilla.org/en-US/docs/Glossary/Global_object)

  • when a JavaScript interpret starts it creates a global object and assign to it a set of properties.
  • properties of the global object are:
    • global constants: undefined, Infinity, NaN
    • global functions: isFinite(), isNaN(), parseFloat(), parseInt(), encodeURI(), decodeURI(), etc.
    • constructor functions: Date(), Array(), Object(), RegExp(), etc.
    • global objects: JSON, Math

How to refer to the global object

  • in client side JavaScript, the global object is represented by the browser's Window object. You can access to the global object by name window. (The window object also defines other global properties that are specific to the web browser and client javascript).
  • in Node, access to the global object by name global

8 Object Data Types

Object
an object is an unordered collection of properties.
A property has a name and a value: the name has string type, the value can have any type.
Array
an array is an ordered collection of elements.
An element has an index and a value: the index is a numeric position, the value can have any type.
Function and Class
functions and classes are not language syntax, but values that can be processed the same way as regular object values

No comments:

Post a Comment