JavaScript


Types, Values

and

Variables

Types, Values and Variables

Types

Numbers

Strings

Booleans

null and undefined

Objects

Immutable / Mutable Types

Type Conversions

Values

Variables

Variable Declaration

Variable Scope




Types


Types


are the kinds of values that can be represented and manipulated in a programming language



JavaScript types can be categorized as follows :


  • primitive / object types
  • mutable / immutable types

Types


Primitive Types

  • numbers
  • strings
  • booleans
  • null
  • undefined


Object Types

any value that does not belong to the primitive type





Numbers

Numbers


JavaScript has a single number type,

there is no distinction between integer values and floating-point values

  all numbers are represented in a 64-bit floating-point format


  •   the largest and smallest numbers that can be represented are:
1.7976931348623157e+308 and 5e-324
  • integers that can be represented exactly are:

9,007,199,254,740,992
and -
9,007,199,254,740,992 (2 or -2 at the power 53)

when a number appears directly in a JavaScript program,

it’s called a numeric literal


Numbers - rounding errors


only a finite number of real numbers can be represented with

the binary floating point format,

which means that when working with them this will often be only an approximation 

! This affects any programming language that uses binary floating-point numbers


However, the values often are very close to the correct value,

adequate for almost any purpose.


The problem arises when attempting to compare values for equality.

! To perform critical financial calculations scaled integers should be used



Number literals







Number literals


Integer literals


  • base 10 = a sequence of digits
  • base 16 (hexadecimal) = '0X' or '0x' followed by hexadecimal digits 0-9 A-F
  • base 8 (octal) = '0' followed by digits 0-7

! Since some implementations support octal literals and some do not,  never write an integer literal with a leading zero. You can't know in this case whether an implementation will interpret it as an octal or decimal value.


Floating-point literals 


the exponential notation 

represents the real number multiplied by 10 to the power of the exponent

Arithmetic operations


work with numbers is done using basic arithmetic operators

  • + addition
  • - subtraction
  • * multiplication
  • / division
  • % modulo (remainder after division)

and 
a set of functions and constants (defined as properties of the Math object)
 for more complex operations
Math.pow(2,53)           Math.round(.6)           Math.ceil(.6)          Math.floor(.6)
Math.abs(-5) Math.max(x,y,z) Math.min(x,y,z) Math.random()
Math.PI Math.E Math.sqrt(3) Math.pow(3, 1/3)
Math.sin(0) Math.log(10) Math.exp(3) Math.log(100)/Math.LN10 Math.log(512)/Math.LN2

Arithmetic

Predefined global variables

  • Infinity to hold the positive infinity (anything larger than the largest representable number)
  • NaN to hold the not-a-number value

! NaN does not compare equal to any other value, including itself.

 This means that you can’t write x == NaN to determine whether the value of a variable x is NaN.

Instead, you should use:

  • x != x - expression which is true if, and only if, x is NaN
  • the function isNaN()  - returns true if its argument is NaN or a non-numeric value such as a string or an object.


The related function isFinite() returns true if its argument is a number other than NaN, Infinity, or -Infinity.


The negative zero value (-0) is also somewhat unusual. It compares equal to positive zero, which means that the two values are almost indistinguishable, except when used as a divisor.


Arithmetic


in JavaScript there are no errors

in cases of overflow, underflow, or division by zero


Overflow

  • when the result of a numeric operation is larger than the largest representable number the result is Infinity
  • similarly, when a negative value becomes larger than the largest representable negative number, the result is -Infinity
  • infinite values - adding, subtracting, multiplying, or dividing  by anything results in an infinite value


Underflow

  • when the result of a numeric operation is closer to zero than the smallest representable number the result is 0
  • if underflow occurs from a negative number “negative zero” is returned 




Arithmetic


Division by zero

 is not an error, it simply returns infinity or negative infinity

! There is one exception, however: zero divided by zero does not have a well-defined value,

and the result of this operation is the special not-a-number value (NaN)


NaN also arises if you attempt to:

  • divide infinity by infinity,
  • take the square root of a negative number
  • use arithmetic operators with non-numeric operands that cannot be converted to numbers

Arithmetic

to sum up the issues explained above: 

Infinity                        // A read/write variable initialized to Infinity.
Number.POSITIVE_INFINITY        // Same value, read-only.
1/0                             // This is also the same value.
Number.MAX_VALUE + 1            // This also evaluates to Infinity.

Number.NEGATIVE_INFINITY        // These expressions are negative infinity.
-Infinity
-1/0
-Number.MAX_VALUE - 1

NaN                             // A read/write variable initialized to NaN.
Number.NaN                      // A read-only property holding the same value.
0/0                             // Evaluates to NaN.

Number.MIN_VALUE/2              // Underflow: evaluates to 0
-Number.MIN_VALUE/2             // Negative zero
-1/Infinity                     // Also negative 0
-0  






Strings


Strings

are JavaScript’s type for representing text


a string is an immutable ordered sequence of 16-bit values, each of which typically represents a Unicode character (UTF-16 encoding )


  the length of a string is the number of 16-bit values it contains


  zero-based indexing is used: the first 16-bit value is at position 0,

the second at position 1 and so on


  the empty string is the string of length 0


  there is no special type that represents a single element of a string,

simply use a string that has a length of 1

String Literals



  to include a string literally simply enclose the characters of the string

within a matched pair of single or double quotes (' or ")


Escape sequences

the backslash character (\) combined with the character that follows

represents a character that is otherwise not represented in the string

(the backslash allows to escape from the usual interpretation) :


  • \0                 - the NUL character (\u0000)
  • \b                 - backspace (\u0008)
  • \t                  - horizontal tab (\u0009)
  • \n                 - newline (\u000A)
  • \v                 - vertical tab (\u000B)
  • \f                  - form feed (\u000C)
  • \r                  - carriage return (\u000D)
  • \"                  - double quote (\u0022)
  • \'                   - apostrophe or single quote (\u0027)
  • \\                  - backslash (\u005C)
  • \x XX          - the Latin-1 character specified by the two hexadecimal digits XX
  • \u XXXX   - the Unicode character specified by the four hexadecimal digits XXXX


if  the \ character precedes any character other than the ones mentioned above, the backslash is simply ignored

Working with strings

concatenation, using the + operator

joins 2 strings, appending the second to the first


the length property - the number of 16-bit values it contains


methods that can be invoked on strings:

  • charAt()
  • substring()
  • slice()
  • indexOf()
  •  lastIndexOf()
  •  split()
  •  toUppercase()
  • replace()

! as strings are immutable, methods like replace() and toUpperCase() return new strings, they do not modify the string on which they are invoked

Pattern Matching

...

scriem aici sau la objects? RegExp Class




Booleans

Booleans


  there are only two values possible for this type

true or false

! reserved words


  are usually the result of comparisons, commonly used in control structures


  any value can be converted to boolean value:

  • undefined, null, 0, -0, NaN, “” convert to false, are called falsy values
  • all other values convert to true, are called truthy values


toString() method can be applied to booleans to convert them

to the strings “true” or ”false”

! there are no other useful methods for booleans

Boolean operators

3 important boolean operators :


&& (AND) operator

evaluates to a truthy value if and only if both of its operands are truthy,

it evaluates to a falsy value otherwise 


| | (OR) operator

evaluates to a truthy value if either one (or both) of its operands is truthy

and evaluates to a falsy value if both operands are falsy


! (NOT) operator

evaluates to true if its operand is falsy and evaluates to false if its operand is truthy



Null

and

undefined

Null

is a language keyword that evaluates to a special value

that is usually used to indicate the absence of a value


it is typically regarded as the sole member of its own type

  it can be used to indicate “no value” for numbers and strings as well as objects


Undefined

  is a predefined global variable

which also indicates the absence of value, a deeper kind of absence

it is the value:

  • of variables that have not been initialized
  • you get when you query the value of an object property or array element that does not exist
  • returned by functions that have no return value
  • of function parameters for which no argument is supplied

Null and undefined

despite the differences, both indicate absence of values

and can be used interchangeably as both are falsy values and behave

like false when boolean value is required


none have got any properties or methods

using . or [] to access a property or method of these values causes a TypeError 


== considers them equal, while === distinguishes them


undefined = system-level, unexpected or error-like absence of value

null = program-level, expected or normal absence of value


! if you need to assign one of these values to a variable or property or pass one of these values to a function, null is almost always the right choice





Objects

Object types

any value that does not belong to the primitive type

(a number, a string, a boolean, null or undefined) is an object


An ordinary object (that is, a member of the type object)

is a collection of properties, where each property has a name (usually a string, including the empty string) and a value (either a primitive value or an object, never undefined)

! no object may have two properties with the same name


an object can also inherit the properties of another object

known as its prototype


the methods of an object are typically inherited properties, and this “prototypal inheritance” is a key feature of JavaScript

Object Literals


objects are useful for collecting and organizing data

the most common things to do with objects are

create them and set, query, delete, test and enumerate their properties


Special kind of objects:

  • arrays
  • functions
  • the global object
  • wrapper objects

Special objects

Array = an ordered collection of numbered values
JavaScript includes a special syntax for working with arrays
 and arrays have some special behaviour that distinguishes them from ordinary objects


Function = an object that has executable code associated with it




it may be invoked to run that executable code and return a computed value

JavaScript defines a special language syntax for working with them


Special objects

The Global Object = a regular object that serves a very important purpose:

its properties are the globally defined symbols that are available to a JavaScript program


When the JavaScript interpreter starts (or whenever a web browser loads a new page), it creates a new global object and gives it an initial set of properties that define:


  • global properties like undefined, Infinity, and NaN
  • global functions like isNaN(), parseInt(), and eval()
  • constructor functions like Date(), RegExp(), String(), Object(), and Array()
  • global objects like Math and JSON


  besides all predefined global values,

the global object also holds program-defined globals

(when a a global variable is declared, that variable is a property of the global object)


  • in top-level code you can use keyword this to refer to the global object
  • client-side, the Window object = global object, it has a self-referential window property that can be used instead of this to refer to the global object

Special objects


Strings, numbers and booleans are not objects, so why do they have properties? Whenever you try to refer to a property, JavaScript converts the string value to an object as if by calling new String(), new Number(), new Boolean()


This object inherits string/number/boolean methods and is used to resolve the property reference. Once the property has been resolved, the newly created object is discarded.


so

Wrapper Objects = the temporary objects created when you access

a property of a string, number, or boolean


! there are no wrapper objects for the null and undefined values: any attempt to access a property of one of these values causes a TypeError

Special objects


it is possible to explicitly create wrapper objects,

by invoking the String(), Number(), or Boolean() constructors:

JavaScript converts wrapper objects into the wrapped primitive value as necessary


the objects usually, but not always, behave just like the values


the == equality operator treats a value and its wrapper object as equal,

the === strict equality operator distinguishes them


the typeof operator will also show you the difference between

a primitive value and its wrapper objects


Immutable

and

 Mutable

Types

Immutable types

primitives - numbers, strings, booleans, null, undefined


their value can't be changed ("mutated")


this is obvious for numbers and booleans

(it doesn’t even make sense to change the value of a number/boolean)

but it is not so obvious for strings


since strings are like arrays of characters,

you might expect to be able to alter the character at any specified index


in fact, JavaScript does not allow this,

and all string methods that appear to return a modified string are, in fact, returning a new string value

Immutable types


primitive values are also compared by value


two values are the same only if they have the same value

for numbers, booleans, null, and undefined
there is no other way that they could be compared

strings are equal if, and only if, they have the same length and if the character at each index is the same

Mutable types


objects

their values can be changed


and


they are not compared by value


two objects are not equal even if

they have the same properties and values 


2 arrays are not equal even if

they have the same elements in the same order

Mutable types


comparison by reference

two object values are the same if and only if

they refer to the same underlying object 


assigning an object or array to a variable simply assigns

the reference: it does not create a new copy of the object


if you want to make a new copy of an object or array,

you must explicitly copy the properties of the object or

the elements of the array 


in order to compare two distinct objects or arrays

their properties or elements must be compared

Type conversions

JavaScript is very flexible about the types of values it requires


when JavaScript expects a certain kind of value,

no matter the value supplied, it will try to convert it as needed


the table below summarizes how values convert from one type to another

Value

Converted to

String

Number

Boolean

Object

undefined

“undefined”

NaN

false

throws TypeError

null

“null”

0

false

throws TypeError

true

“true”

1


new Boolean(true)

false

“false”

0


new Boolean(false)

“” (empty string)


0

false

new String(“”)

“1.2” (nonempty,numeric)


1.2

true

new String(“1.2”)

“one” (nonempty, non-numeric)


NaN

true

new String(“one”)


Type conversions


Value

Converted to

String

Number

Boolean

Object

0

"0"


false

new Number(0)

-0

"0"


false

new Number(-0)

NaN

“NaN”


false

new Number(NaN)

Infinity

“Infinity”


true

new Number(Infinity)

-Infinity

“-Infinity”


true

new Number(-Infinity)

1 (finite, non-zero)

"1"


true

new Number(1)

{} (any object)

*

**

true


[] (empty array)

""

0

true


[9] (1 numeric elt)

"9"

9

true


['a'] (any other array)

use join() method

NaN

true


function(){} (anu function)

*

NaN

true


Type conversions

object-to-boolean conversions are trivial: all objects convert to true

but 

object-to-string and object-to-number conversions are more complicated

 these are performed by invoking a method of the object to be converted


objects inherit two different methods that perform conversions


toString() returns a string representation of the object

and 

valueOf()is supposed to convert an object to a primitive value that represents the

object, if any such primitive value exists


Type conversions


toString()
method
  by default does not return a very interesting value

 ({x:1, y:2}).toString()                        // => "[object Object]"

many classes define more specific versions of the toString() method:

 [1,2,3].toString()                 // => "1,2,3"

 (function(x) { f(x); }).toString() // => "function(x) {\n f(x);\n}"

 /\d+/g.toString()                  // => "/\\d+/g"

 new Date(2010,0,1).toString()      // => "Fri Jan 01 2010 00:00:00 GMT-0800 (PST)" 

Type conversions

valueOf() method

a less well-defined conversion function


objects are compound values, and most objects cannot really be represented by a single primitive value, so by default the method simply returns the object itself rather than returning a primitive


primitives - wrapper classes define valueOf() methods that return the wrapped primitive value

arrays, functions and regular expressions simply inherit the default method which returns the object itself

Date class - defines a valueOf() method that returns the date in its internal representation, the number of milliseconds since January 1, 1970

Type conversions


* convert object to string


1. object has a toString() method => JavaScript calls it

returned value is a primitive? => it is converted to a string (if not already a string) and returned


2. object has no toString() method or the method does not return a primitive
=> JavaScript looks for valueOf()
and calls it if method exists

returned value is a primitive? => it is converted to a string (if not already a string) and returned


3. TypeError is thrown, if no primitive value can be obtained from either toString() or valueOf()

Type conversions


** convert object to number


1. object has a valueOf() method => JavaScript calls it

returned value is a primitive? => it is converted to a number (if necessary) and returned


2. object has no valueOf() method or the method does not return a primitive
=> JavaScript looks for toString()
and calls it if method exists

returned value is a primitive? => it is converted to a number (if not already a number) and returned


3. TypeError is thrown, if no primitive value can be obtained from either valueOf() or
toString()

Type conversions

for

+ / == / != / relational operators (<,>,<=,>=)


if either of the operands is an object, it is converted using a special object-to-primitive conversion rather than the object-to-number conversion used by the other arithmetic operators


for

+ / == /!= 

the conversion includes a special case for Date objects


the object-to-primitive conversion is basically an object-to-number conversion (valueof() first) for all objects that are not dates, and an object-to-string conversion (toString() first) for Date objects


the primitive value returned by valueOf() or toString() is used directly without being forced to a number or string


Type conversions


Conversions and equality


because JavaScript can convert values flexibly,

its == equality operator is also flexible with its notion of equality

0

 null == undefined                   // these values are treated as equal
 "0"  == 0                           // string is converted to a number before comparing
  0   == false                       // boolean is converted to number before comparing
 "0"  == false                       // both operands convert to number before comparing
but
!!! the convertibility of one value to another does not imply equality of those two values
 undefined == false                  // not true, as == operator never attempts to
                                     // convert its operands to booleans

exactly what conversions are performed by the == operator and a description of the strict equality operator ===, which does not perform conversions when testing for equality, will be discussed later in the course

Type conversions


Explicit conversions


although many type conversions are performed automatically,

sometimes explicit conversions are needed


invoking the functions Number(), String(), Boolean() and Object()

without the new operator


 Number("3")                           // => 3
 String(false)                         // => "false" or use false.toString()
 Boolean([])                           // => true
 Object(3)                             // => new Number(3)
 Object()                              // => creates an empty object

attempting to convert null or undefined to an object => TypeError

Type conversions


certain operators perform implicit type conversions and are sometimes used for the purposes of type conversion, these will also be discussed more detailed later

 x + ""    // + converts the second operator to string if one operator is a string
 +x        // unary + operator converts its operand to number
 !!x       // unary ! operator converts its operand to a boolean and negates it

for formating and parsing numbers there are specialized functions which provide more precise control over number-to-string and string-to-number conversions

toString() defined by the Number class
accepts optional argument as base for the conversion
 var n = 17;
 binary_string = n.toString(2)            // evaluates to "10001"
 octal_string = "0" + n.toString(8)       // evaluates to "021"
 hex_string = "0x" + n.toString(16)       // evaluates to "0x11"

Type conversions

number-to-string

when working with financial or scientific data, needing to have control

over the number of decimal places,

or the number of significant digits in the output,

or whether exponential notation is used

convert number to strings using three methods defined by the Number class:


toFixed() - converts a number to a string with a specified number of digits after the decimal point

toExponential() - converts a number to a string using exponential notation, with one digit before the
decimal point and a specified number of digits after the decimal point

toPrecision() - converts a number to a string with the number of significant digits you specify


 var n = 123456.789;
 n.toFixed(0);               // "123457"
 n.toFixed(2);               // "123456.79"
 n.toFixed(5);               // "123456.78900"
 n.toExponential(1);         // "1.2e+5"
 n.toExponential(3);         // "1.235e+5"
 n.toPrecision(4);           // "1.235e+5"
 n.toPrecision(7);           // "123456.8"
 n.toPrecision(10);          // "123456.7890"

Type conversions

string-to-number


Number()

attempts to parse the string as an integer or floating point, only works for base-10 integers and does not allow trailing characters that are not part of the literal


there are two global functions (not methods of any class) which are more flexible:

parseInt() - parses only integers, if string begins with "0x"/"0X" interprets number as hexadecimal

parseFloat() - parses integers and floating-point functions

both functions skip leading whitespace, parse as many numeric characters as they can, and ignore anything that follows

if the first nonspace character is not part of a valid numeric literal, they return NaN

 parseInt("3 pieces")   // => 3
 parseInt("-12.34")     // => -12
 parseInt("0xff")       // => 255
 parseInt("0XFF")       // => 255
 parseInt("-0XFF")      // => -255
 parseInt("0.1")        // => 0
 parseInt(".1")         // => NaN: integers can't start with "."
 // optional second argument specifies the base of the number to be parsed, values 2-36
 parseInt("11",2)       // => 3 ( 1*2 + 1 )
 parseInt("ff",16)      // => 255 ( 15*16 + 15 )
 parseInt("zz",36)      // => 1295 ( 35*36 + 35 )
 parseInt("077",8)      // => 63 ( 7*8 +  7)
 
 parseFloat("3.14 meters")      // => 3.14
 parseFloat(".1")               // => 0.1
 parseFloat("$72.47")           // => NaN: numbers can't start with "$"





Values

Values


computer programs work by manipulating values


in computer science, a value is an expression which cannot be evaluated any further (a normal form)


the members of a type are the values of that type


in JavaScript values are converted liberally from one type to another, which affects definition of equality (== vs ===)


when a program needs to retain a value for future use, it assigns the value to (or “stores” the value in) a variable






Variables

Variables



A variable defines a symbolic name for a value

and allows the value to be referred to by name



Variables...in JavaScript


 are declared with the var keyword
var message = "I'm a variable";
the same var keyword can be used to declare multiple variables
 var i, j = 0, k;

  repeated declarations are legal and harmless


omitted declarations 

in non-strict mode, assigning a value to an undeclared variable actually creates that variable as a property of the global object which works much like, but not exactly the same as, a properly declared global variable

but

! it's a bad habit, source of many bugs


initialization

if an initial value is not specified with the var statement,

the variable is undefined until the code stores a value in it


variables are untyped

you can assign a value of any type to a variable, and you can later assign a value of a different type to the same variable

Variables

the scope of a variable is

the region of your program source code in which it is defined


Lexical scoping 


variables declared outside a function are global variables,

have global scope

and

are visible (defined) throughout the program


variables declared inside a function are local variables,

have function scope

and

are visible only to code that appears inside that function

(including within any functions that are nested within that function)

Variables



function parameters also count as local variables and are defined only within the body of the function 


within the body of a function, a local variable

takes precedence over a global variable with the same name


local variables must always be declare with var,

otherwise the global variable is used


function definitions can be nested,

each function has its own local scope


hoisting

all variables declared within a function are visible

throughout the body of the function

=> they are visible even before they are declared


JavaScript code behaves as if all variable declarations in a function

(but not any associated assignments) are “hoisted” to the top of the function (as opposed to "block scope")

Variables



 var scope1 = "global1",                // declared three global variable
     scope2 = "global2",
     scope3 = "global3";

 function checkscope() {

     console.log(scope1);               // prints undefined, not "global1" -> hoisting
     var scope1 = "local1";             // declared a local variable with the same name
     scope2 = "local2";                 // changed the value of the global variable
     var myscope = "myLocal"            // declared a local variable
     return [scope1, scope2, myscope];  // returned three values

 }

 checkscope();                          // ["local1", "local2", "myLocal"]
 scope1;                                // "global"
 scope2;                                // "local2", global variable has changed

Variables


when declaring a global variable, it actually means defining
a property of the global object


if the var keyword is used, the property that is created is nonconfigurable, which means that it cannot be deleted
with the delete operator


otherwise 


undeclared variables are regular, configurable properties of
the global object and they can be deleted


local variables can be thought of as the properties of an object associated with each function invocation ("call object")


JavaScript allows to refer to the global object with the this keyword,

but it does not give any way to refer to the object in which local variables are stored

Variables


every chunk of JavaScript code (global code or function)

has a scope chain associated with it


the Scope Chain

 is a list or chain of objects that defines the variables that are “in scope” for that code

when JavaScript needs to look up the value of a variable x (process called variable resolution) it starts by looking at the first object in the chain and moves on to the next objects until it finds an object that has a property named x, whose value is used.

if x is not a property of any of the objects in the scope chain, then
x is not in scope for that code, and a ReferenceError occurs

Types, Values and Variables

By Azaleea Cristina Constantinescu