Advanced Data Types - Data Conversion and Constructor - JAVASCRIPT: A Beginner’s Guide to Learning the Basics of JavaScript Programming (2015)

JAVASCRIPT: A Beginner’s Guide to Learning the Basics of JavaScript Programming (2015)

Chapter 19. Advanced Data Types - Data Conversion and Constructor

Like other programming languages, JavaScript have built-in data structures. However, these usually differ according to the language. In this chapter, we will try to list all the built-in data structures used in JavaScript and the properties they include. You can also use them to construct other data structures. If possible, other programming languages are drawn.

Dynamic Typing

JavaScript is a dynamic language or a loosely typed. Hence, there is no need to declare the variable type earlier. The type will be automatically determined while you are processing the program. So it will also mean that we can have similar variable as various types:

Data Types

Based on the latest ECMA Script, the standard defines seven types of data:

Primitive Data Types

· Null

· Number

· Boolean

· Undefined

· String

· Symbol (added in ECMA Script 6)

· And Object

Primitive Values

All kinds except objects describe values that are fixed. For instance, Strings are immutable, which is not similar to C. These values are primitive values.

Null Type

This type only has one value, which is null.

Boolean Type

Boolean describes a logical entity, and could only have two values: true and false.

Undefined Type

A value is considered as undefined if its variable has not been assigned.

Number Type

There is only one number type based on the ECMAScript standard. This is the range between –(253 -1) and 253 -1) or double-precision 64-bit binary format IEEE 754 value. Take note that there’s no certain kind of integers. Aside from the ability to signify floating-point number, the number type also has three values that are symbolic: NaN (Not a Number), -Infinity, and +Infinity.

In order to check for smaller of larger values compared to positive/negative Infinity, we can utilize the constants Number.MIN VALUE or the Number.MAX VALUE and beginning with the ECMAScript 6, we can also check if the number is of double precision floating point through Number.isSafeInteger() and the Number.MIN SAFE INTEGER and Number.MAX SAFE INTEGER. Outside this range, the JavaScript numbers are not anymore safe.

The number type with only a single integer has two major representations: 0 can be +0 or -0. Zero is a default for +0. This has almost zero impact in the praxis. For instance, +0===-0 is true. But you will take note of this if you use 0 as a divisor:

> 34 / +0

Infinity

>34 / -0

-Infinity

Even though the number usually signifies only the value, JavaScript can offer several binary operators. We can use them to signify several Boolean values in one number through bit masking. This is often regarded as a malpractice. But JS provide no other methods to signify a Boolean set such as an array of Booleans or an object with Boolean values defined to name the properties.

Bit masking also has the tendency to make the code hard to read, interpret, and keep. It is important to use these strategies in very limited environments such as when you try to cope with the limitation of storage or in extreme cases if every bit over the network will count. You should only consider this strategy if this is the only option you can use for size optimization.

String Type

The String type in JavaScript is utilized to signify textual type of data. This is a set of values unsigned 16-bit integer. Every element in the String will occupy a position in the String. The first element is within index 0, and the next will be 1, and 2, and so forth. The String length refers to the number of values within.

Not similar to programming languages such as C, the Strings in JS are immutable. Hence, when you create a string, you can’t modify it. But it is still possible to make another string depending on an operation of the original string. This is true of the original substring by choosing individual letters or by calling the String.substr(). This is also true for a concatenation of two individual strings by using the addition operator or by calling String.concat().

Code String Typing

You may be tempted to use strings to signify complicated data. This method has some short-term advantages:

· Debugging is easy with string. Anything inside the string will be printed.

· A lot of APIs such as XMLHttpRequest, local storage values, and input fields are using Strings as common denominator.

· It’s easy to create complicated strings using concatenation

Conventionally, it is possible to signify any data structure using a string. But this is not a good idea. For example, you can emulate a list using a separator even though a JS array is a more ideal solution. But if we use a separator in the list elements, there is the tendency for the list to be broken. You can still choose an escape character, but still this method will require a lot of conventions and will just create unnecessary maintenance problem.

It is ideal to use strings only for textual data. In signifying complicated data, you can parse strings and utilize the suitable abstraction.

Symbol Type

The JS ECMAScript 6 features Symbols, which are unique and immutable primitive value and could be used as the key of an Object property. In some languages, Symbols are known as atoms. While in C, they can be compared to enum.

Objects

In programming, an object refers to a value in memory that is possibly referenced by an identifier.

Properties

In JS, objects could be regarded as a group of properties. Using the object literal syntax, you can initialize a limited set of properties, which you can easily add or remove. The values of property could be of any type, which includes other objects that will enable creating complicated data structures. You can identify properties using key values, which could either be a Symbol or a String value.

We have two kinds of object properties that have specific attributes – The accessor property and data property.

Accessor Property

This property associates a key with one or two accessor functions in order to store or retrieve a value. This property has the following attributes:

ATTRIBUTE

TYPE

DEFAULT VALUE

DESCRIPTION

[[Configurable]]

Boolean

False

If false, you can’t delete the property and you can’t change it to a data property.

[[Enumerable]]

Boolean

False

If true, you can enumerate the property in for…in loops.

[[Set]]

Undefined or Function Object

Undefined

You can call this function using an argument containing the assigned value This will be executed once you specify property to be changed

[[Get]]

Undefined or Function Object

Undefined

You can call this function using an empty arg list and retrieve the value property if you perform a get access to the value

Take note that attribute is often use in JS engine. Hence, there is no way to directly access it. Hence, the attribute is written within two squared braces rather than one.

Data Property

Data property relates a key with a value. It has the following attributes:

ATTRIBUTE

TYPE

DEFAULT VALUE

DESCRIPTION

[[Configurable]]

Boolean

False

If false, you can’t delete the property and you cannot change the attributes other than the [[Writable]] and [[Value]].

[[Enumerable]]

Boolean

False

If true, you can enumerate the property for…in loops.

[[Writable]]

Boolean

False

If false, you can’t change the [[Value]] property

[[Value]]

Any Type

Undefined

You can retrieve the value through a property’s get access.

The following attributes became obsolete in the ECMA Script3, and renamed in the ECMA Script5.

Attribute

Type

Description

DontDelete

Boolean

[[Configurable]] attribute – reverse state of ES5

DontEnum

Boolean

[[Enumerable]] attribute – reverse state of ES5

Read-only

Boolean

[[Writable]] attribute – reverse state of ES5

Accessor Property

The accessor property relates a key with get and set functions in order to store or retrieve value. The following has its attributes:

Attribute

Type

Default Value

Description

[[Configurable]]

Boolean

False

If false, you can’t delete the property and you can’t change it to data property.

[[Enumerable]]

Boolean

False

If true, you can enumerate the property for…in loops

[[Set]]

Undefined or Function Object

Undefined

You can call the function using an arg containing the assigned value and executed if you try to change a specified property.

[[Get]]

Undefined or Function Object

Undefined

You can call the function using an empty arg list and restore the value property by performing a get access to the value.

“Normal” Functions and Objects

A JS object is considered as a mapping between values and keys. Keys are Symbols or Strings while values could be anything. This will make the object a normal fit for hashmaps. Meanwhile, functions are normal objects, which can be called.

DATA CONVERSION

Java is a loosely typed language. Hence, as a programmer, you still need to consider the actual kind of values that you are dealing. A usual error in browser scripting is to read the property value of a form control that the user can type a number and will add this value to a different number. The property values of form controls are strings. Even the characters the series contains still signify a number. Trying to add a string to a value, even if this value is a number, will result to the second value type-converted into a string, which is concatenated to the end of the first string value originating from the form control. This error is caused by the dual nature of the positive operator used for numeric addition as well as string concatenation. Hence, the nature of the operation performed is distinguished by the context where the operands are numbers to begin with will the positive operator will execute addition. Or else, it transforms all the operands to strings and performs concatenation.

The discussions that follow is illustrated using tables of values generated using JavaScript conversion operations. The headers of the tables show the value as signified in the JS source code used instead of their internal representation.

For instance, 321e-2 as a number was the character series encoded in the source code. This will be interpreted as a number value of 3.21. The different values here have been selected to show the aspects of conversion type. Take note that these aspects may not be true to all the tables presented. But all the test values are included in the tables for complete comparison, except where no type of conversion happens. The table bodies list all the results of the different type operations conversion.

Conversion to Boolean

In assessing the expression of an if statement, the JavaScript interpreter will type-convert the result of this expression into Boolean so it could arrive into a decision. Meanwhile, different operators type-convert their operands to Boolean to identify its action, including the logical operators such as Not (!), OR (||), and AND (&&). The operator NOT will convert the operand into Boolean and if its value is true, it will return false, and if false, it will return true. Because the result of a NOT operation is a Boolean value, which is the inverse of the type-converted veracity of the operand. Two NOT operations combined will yield a Boolean value, which is equal to the result of the type-conversion of the Boolean operand:

You can use this method to produce the tables below.

Another method of producing a Boolean value, which represents the type-converted veracity of a value is to pass this value to the function called Boolean constructor.

Numeric Values: Double NOT (!!col)

NaN

+Infinity

-Infinity

321e-2

16.8

16

8

1.6

1

+0

-0

-1.6

!!col

false

true

true

true

true

true

true

true

true

false

false

true

If the numbers are transformed into a Boolean, zero will become false. Other numbers will be true except of the special numeric value Not a Number (NaN) used if another kind is transformed to a number, but this conversion will not result in a sensible number. Take note that NaN is always false. The values of negative and positive infinity, while not finite values, are non-zero numbers and will always type-convert to a true Boolean.

String Values: Double NOT (!!col)

“xx”

“-0x10”

“-010”

“0xFF” (Hex)

“0x10”

(Hex)

“010”

(Octal)

“321e-2”

“16.8”

“16”

“8”

“1.6”

“1”

“0”

“-1.6”

“”

(empty string)

!!col

true

true

true

true

true

true

true

true

true

true

true

true

true

true

true

false

The rules are even easier to understand for converting string to Boolean, because all non-empty strings will be true and empty strings will be false.

Other Values: Double NOT (!!col)

function(){return;}

new Object()

false

true

null

undefined

!!col

true

true

false

true

false

false

Null and Undefined will be converted to Boolean false values, which are not converted, while functions are always true.

This is the most important aspect of type-converting to Boolean, because it permits a script to differentiate between properties in an environment, which could be undefined or could refer to an object. Considering a null or an undefined value as an object will result to errors. Hence, if you are in doubt, code can prevent producing errors by wrapping the code, which likes to gain access an object in the test if. Including the suspect reference to the expression object will be converted into Boolean, and the result will be false if the object is not existing while true if it is existing.

The double NOT operation will allow the setting of Boolean flags, which you can use to signify the existence of different objects:

Conversion to String

As discussed earlier, conversion type to a string will usually result from the action of the positive operator if one operator is not a number. The simplest way to get the string, which results from the conversion type is through concatenation of value to an empty string. This technique is often used to produce the tables below.

Another way is to convert a value into a string to pass it as an arg to the constructor string called as function:

Numeric Values: type-convert to string (“” + col)

NaN

+Infinity

-Infinity

321e-2

16.8

16

8

1.6

1

+0

-0

-1.6

“”+col

NaN

Infinity

-Infinity

3.21

16.8

16

8

1.6

1

0

0

-1.6

Take note that the number produced from the source code 321e-2 has generated the string 3.21, as this string signifies the internal number generated from the source code. But the internal number of JavaScript will take the form of double precision IEEE floating point, and which means that we cannot signify the numbers with precision. The outcome of the operations could only yield close estimates and if they are converted into strings, this string will signify the estimate and could be undesirable or unexpected. This is usually needed to use custom functions to yield string representations of numbers in the format you need. Rare is the case that the type conversion mechanism is suited to generate numeric output needed for presentation.

Other Values: type-convert to string (“” + col)

function(){return;}

new Object()

false

true

null

undefined

“”+col

Function(){return;

}

[object Object]

false

true

null

undefined

If you type convert the functions or objects to strings, you need to call their toString method. These will default into the Function.prototype.toString and Object.prototype.toString but this could be overloaded with a function called to a “toString” property of the function/object. Type conversion of a function into a string doesn’t always lead to the source code of the function. The behavior of Function.prototype.toString is dependent on the implementation and could vary a lot, like the outcome from the methods and host objects. This includes the methods and objects provided by the environment including the DOM elements.

Conversion to Numbers

Conversion of values to numbers, especially strings to numbers, is a common requirement and you can use different methods. Any numerical operator aside from the addition and concatenation operator will force type-conversion. Hence, the conversion of a string to a number may involve performing a mathematical operation on the representation of a string, which will not affect the outcome number like multiplying by one or subtracting zero.

But the unary + operator will also type-convert the operand to a number, as it will not perform any more mathematical operations, it will be the easiest method for type-conversion of a string into a number.

Meanwhile, the unary – operator will also include the type-conversion of the operand if needed aside from negating the value.

Even though the unary + is the quickest way to convert a string into a number, you can still use a final method, which will use the JavaScript type conversion for algorithms. You can call the constructor Number as the argument while the return value will be the number, which represents the type-conversion of the result.

The constructor Number is a slow form of the type-conversion methods. However, if speed is not an overriding element, it will generate an easier-to-understand source code.

The tables below show the outcomes of type-converting into a number through the unary + operator. But take note that all the preceding alternative method will generate the same outcome as they all use precisely the same algorithm to perform the conversion.

String Values: Type Conversion to Number (+col)

“xx”

“-0x10”

“-010”

“0xFF”

(Hex)

“0x10”

(Hex)

“010”

(Octal)

“321e-2”

“16.8”

“16”

“8”

“1.6”

“1”

“0”

“-1.6”

“”

(empty string)

+col

NaN

NaN

-10

255

16

10

1.23

16.8

16

8

1.6

1

0

-1.6

0

In converting strings to numbers, it is important to consider the type conversion outcomes from the strings, which do not signify numbers. The empty string will be converted into the number zero, which depends on the application could be damaging to the code. Still, it is crucial to be aware of the risk. In other context strings that follow the JS format for octal number could be disastrous. However, the conversion will still treat them as base 10. But the strings, which follow the format for Hex numbers will be interpreted as hexadecimals. Meanwhile, the strings that cannot be interpreted as a number-type will be converted to NaN that could be checked for the isNan function. Strings that represent numbers in an exponential format (“321e-2”) are interpreted alongside minus symbols.

Other Values: Type-Convert to Number (+col)

function(){return;}

new Object()

false

true

null

undefined

+col

NaN

NaN

0

1

0

NaN

Functions and objects are always type-converted into NaN numbers similar to undefined values. It is also important to take note that null will be type-converted to zero. Possibly because this will be type-converted to Boolean first and then to number. If you take a closer look at the Boolean results in the preceding table, null will be converted into Boolean false that will then become numeric zero. There is no need to type-convert these value types to numbers. The conversion is only relevant by considering the accidental outcome of value conversion, which is expected to be a string but could really be performing arithmetic operations using a value as an operand.

Parsing to Number

Another way of changing a string to number is through a global function designed to parse a string and return a number. The function parseFloat will accept a string argument and will return a floating point number, which will result from parsing that string. Non-string args will be type-coverted first to a string as discussed earlier. The functions for string functions will be interpreted in the string based on every character until they stumble upon a character, which should not be part of the number. At this point, they will stop and yield a number based on the characters, which they have interpreted that should not be part of that number. You can fully exploit this feature, for instance, through a string signifying a CSSlength value like parseFloat “34.6eh. The “eh” will be ignored because these characters cannot be added with the preceding set to generate a valid number. The printed number would only be 34.6, which is the numeral composition of the CSS and refined of its units.

parseFloat

String Values: parseFloat(col)

“xx”

“-0x10”

“-010”

“0xFF”

(Hex)

“0x10”

(Hex)

“010”

(Octal)

“321e-2”

“16.8”

“16”

“8”

“1.6”

“1”

“0”

“-1.6”

“”

(empty string)

parseFloat(col

NaN

0

-10

0

0

10

3.21

16.8

16

8

1.6

1

0

-1.6

NaN

Through the parseFloat function, the empty string will generate NaN, along the strings that cannot be subject to numerical interpretation. The exponential format is interpreted and the primary zero in the octal format will not block the reading of the string as a decimal number. Hexadecimal strings could be read as the number zero, as the following “x” will not be read as part of a number. Hence, parsing will stop after the primary zero.

function(){return;}

new Object()

false

true

null

undefined

parseFloat+col

NaN

NaN

NaN

NaN

NaN

NaN

The non-string values are first changed into a string, which is used through the parseFloat. Because the type-conversion to a string will not usually lead in a string that could be read as a number, the result will be NaN. The functions and objects could have a custom method toString, which could return strings that could be seen as numbers but this will be a special need.

parseInt

The function parseInt will behave like the function parseFloat, aside from its feature of reading the string argument as an integer and as an outcome will recognize fewer characters as potential candidates to be part of this number. You can also use parseInt to convert a floating point number into integer. However, this is not an ideal method, because if the argument is of numeric type, this will be changed into a string and then will be parsed as a number. This method can be very inefficient. This could generate conflicting outcomes with numbers like 3e-300, in which the next smaller integer will be zero. But the parseInt will yield 2.

In addition, because of the numerical format employed by JavaScript, the numbers are usually signified by near estimates. For instance, 1/6+1/3+1/2 = 0.999999, which will not be interpreted as one. Through the function parseInt, the equation will result to zero if you call it to act on the operation result.

In rounding integers to one, Math.floor and Math.round.Math.ceil are more ideal. For a desired outcome, which could be expressed as a 32-bit signed integer, the bitwise operation shown below could also be suitable:

Numeric Values: parseInt(col)

NaN

+Infinity

-Infinity

321e-2

16.8

16

8

1.6

1

+0

-0

-1.6

parseInt(col)

NaN

NaN

NaN

1

16

16

8

1

1

0

0

-1

If it is acting on number, the result of the argument’s early type-conversion to a string will be clear on the results. Take note that the value 3210-2 is the number 3.21 internally, and this type will be converted into the string “32.1”. Hence, the entry in the table above could look odd, but the results are actually right.

String Values:parseInt(col)

“xx”

“-0x10”

“-010”

“0xFF”

(Hex)

“0x10”

(Hex)

“010”

(Octal)

“321e-2”

“16.8”

“16”

“8”

“1.6”

“1”

“0”

“-1.6”

“”

(empty string)

parseInt(col)

NaN

-16

-8

255

16

8

321

16

16

8

1

1

0

-1

NaN

Strings in the hexadecimal and octal number formats will signify integers and parseInt can read them according to the rules of JS source code, even if they have leading minus symbols.

Other Values: parseInt(col)

function(){return;}

new Object()

false

true

null

undefined

+col

NaN

NaN

NaN

NaN

NaN

NaN

As the parseInt performs type-conversion of the non-string args to strings, it will always generate the same outcomes for function, object, undefined, null, and Boolean arguments like in parseFloat.

ToInt32

ToInt32 is an internal function, which you can only use in the JS implementation, and you cannot call directly from the scripts similar to the method for parseInt. This is a bit off relevant to the topic of converting Javascript values into numbers, but this could be used in special cases.

The bitwise operators such as AND (&) and OR (|) are operating on numbers, so they are type-converting the operands into numbers. But they can still operate on 32-bit signed integers. Hence, with the numerical value, they call the internal ToInt32 function with the number as the argument and use the returned value as the operand. This returned value is a constant 32-bit integer.

The result could be similar to parseInt added with type-conversion of numbers. Even though the outcome is restricted in range to 32 bits, this is always numerical and not +/- Infinity or NaN.

Similar to using numerical operators for operations with no effect on the value of any number, it is still doable to do a bitwise operation, which has no effect on the value yielded by calling the ToInt32. The following tables were produced through a zero or a bitwise operation.

Numeric Values: ToInt32(col|0)

NaN

+Infinity

-Infinity

321e-2

16.8

16

8

1.6

1

+0

-0

-1.6

col|0

0

0

0

3

16

16

8

1

1

0

0

-1

Notice that –Infinity, +Infinity, and NaN are all changed to zero, while the floating point values were truncated to integer.

String Values: ToInt32(col|0)

“xx”

“-0x10”

“-010”

“0xFF”

(Hex)

“0x10”

(Hex)

“010”

(Octal)

“321e-2”

“16.8”

“16”

“8”

“1.6”

“1”

“0”

“-1.6”

“”

(empty string)

(col|0)

0

0

-10

255

16

10

1

16

16

8

1

1

0

-1

0

The string values, which will be type-converted into NaN will be converted into as zero from ToInt32.

Other Values: ToInt32(col|0)

function(){return;}

new Object()

false

true

null

undefined

col|0

0

0

0

1

0

0

The undefined functions and objects are transformed to zero through this operation. Remember, the Boolean true will be changed to the value of 1.

Conversion of User Input

Many of the mechanisms for obtaining user input as well as prompt, generate results in string forms. If you expect the user to input a number, it is still needed to enter something. If you need to convert a string into a number for future operations, you can use any method discussed above, just make certain that the method will be suitable to the input of the nature. Results with some typos or erroneous data could be challenging to detect and manage.

Before changing a string to a number, it may be ideal to employ a Regular Expression in order to check the content of the string to make certain that they are conforming to a format that is acceptable. This will serve to get rid of the string values, which may otherwise suffer from the nuances of the string to number that converts processes if applied to string values that are unexpected.