JAVASCRIPT

THE BASICS

Expressions & Operators

an expression is a phrase 

that an interpreter
can evaluate to produce a value

complex expressions 

are built from simpler expressions

using operators

3 + 4
a * b
c = 7

an operator combines the values of its operands
&
evaluates to a new value

Primary Expressions

primary expressions
are constant or literal values
language keywords & variable references

15.67            //=> number literal
'JavaScript'     //=> string literal
/[a-zA-Z0-9]/    //=> regular expression literal
null             //=> evaluates to `null` value
false            //=> evaluates to boolean `false` value
this             //=> evaluates to `current` object
undefined        //=> evaluates to global variable `undefined`
title            //=> evaluates to the value of `title` variable

Object & Array
Initializers

object & array initializers

are expressions whose values

are a newly created object or array

array initializer

are a comma-separated list of expressions

placed between square brackets

[14 + 1, 10 + 5, 30 / 2]   //=> [15, 15, 15]

object initializer

are a comma-separated list of expressions

placed between curly brackets

where each expression is prefixed by a name

var obj = { 
  first: 14 + 1, 
  second: 10 + 5,
  third: 30 / 2
};

console.log(obj);     //=> Object {first: 15, second: 15, third: 15}

the expressions in an object or array initializer

are evaluated each time the initializer is evaluated
 

this means that the value of the expressions

may be different each time it is evaluated

Function Definition
Expressions

a

function definition expression

defines a JavaScript function

&

the value is the newly created function

var multiply = function (a, b) {
  return a * b;
};

Property access

expressions

property access expressions
evaluate to the value of an object property

or an array element


there are two syntaxes defined for property access

dot notation
expression.identifier

var obj = {
  a: 15
};

obj.a //=> 15

where the expression specifies the object & the identifier specifies the name of the property to be accessed

&

bracket notation
expression[expression]

var obj = {
  ab: 15
};

obj['a' + 'b']  //=> 15
obj['ab']       //=> 15

where the first expression is followed by another expression enclosed in square brackets whose value has to be the name of the desired property

the expression before the . or [ is first evaluated

if the value is null or undefined it throws a TypeError

dot notation syntax is the simpler of the two
BUT
it can only be used when the property that needs to be accessed
is a legal identifier

var obj = {
  a: 15,
  b: [7.5, 7.5],
  c: {
    d: {
      e: 30 - 15
    }
  }
};

var arr = [ 1, 'JavaScript', obj, function () { return obj; } ];

obj.a                    //=> 15
obj.b[1]                 //=> 7.5
obj.c.d.e                //=> 15
obj['c']['d'].e          //=> 15
obj['a' + 'b'][0]        //=> TypeError: Cannot read property '0' of undefined

arr[0]                   //=> 1
arr[2].a                 //=> 15
arr[2]['c']['d']['e']    //=> 15
arr[3]().c.d.e           //=> 15

a more complex example

Invocation Expressions

invocation expressions
are JavaScript's syntax for executing functions or methods

someFunction(15); // `someFunction` is the function expression & `15` is the argument expresion

var obj = {
  age: null,
  setAge: function (age) {
    this.age = age;
  },
  getAge: function () {
    return this.age;
  }
};

obj.setAge(15);  //=> obj.age value is now 15
obj.getAge();    //=> 15 - returns the obj.age value

when an invocation expression is evaluated
the function expression is evaluated first

&

then the argument expressions are evaluated

to produce a list of argument values

if the value of the function expression

is not a callable object it throws a TypeError

Object.push(obj, 'title', 'JavaScript - The Basics');
//=> TypeError: undefined is not a function

next if callable

argument values are assigned to parameter names

&

then the function body is executed

Object Creation
Expressions

an

object creation expression
creates a new object & invokes a function to initialize the properties of that object

 

this function is called constructor

object creation expressions 
are like invocation expressions 
except they are prefixed by the new keyword

function Course(title) {
  this.title = title || 'Untitled';
}

var course = new Course('JavaScript - The Basics'); 

console.log(course); //=> Course {title: "JavaScript - The Basics"}

Operators overview

operators

are used in

arithmetic / comparison / logical /
assignament / relational / evaluation / special

expressions

operators
are punctuation characters like + or =

or

keywords such as delete and typeof

Operator Operation Associativity Number of operands Types
++ pre- or post-increment right-to-left 1 lval num
-- pre- or post-decrement right-to-left 1 lval num
- negate number right-to-left 1 num num
+ convert to number right-to-left 1 num num
~ invert bits right-to-left 1 int int
! invert boolean value right-to-left 1 bool bool
delete remove a property right-to-left 1 lval bool
typeof determine type of operand right-to-left 1 any str
void return undefined value right-to-left 1 any undef
*, /, % multiply, divide, remainder left-to-right 2 num, num num
+, - add, subtract left-to-right 2 num, num num
+ concatenate strings left-to-right 2 str, str str
<< shift left left-to-right 2 int, int int

the below table lists all JavaScript operators
ordered by their precedence
(first having heigher precedence)

horizontal blue lines separate operators with different precedence levels

Operator Operation Associativity Number of operands Types
>> shift right with sign extension left-to-right 2 int, int int
>>> shift right with zero extension left-to-right 2 int, int int
<, <=, >, >= compare in numeric order left-to-right 2 num, num bool
<, <=, >, >= compare in alphabetic order left-to-right 2 str, str bool
instanceof test object class left-to-right 2 obj, func bool
in test whether property exists left-to-right 2 str, obj bool
== test for equality left-to-right 2 any, any bool
!= test for inequality left-to-right 2 any, any bool
=== test for strict equality left-to-right 2 any, any bool
!== test for strict inequality left-to-right 2 any, any bool
& compute bitwise AND left-to-right 2 int, int int
^ compute bitwise XOR left-to-right 2 int, int int
| compute bitwise OR left-to-right 2 int, int int
&& compute logical AND left-to-right 2 any, any any
|| compute logical OR left-to-right 2 any, any any
? : choose scond or third operand right-to-left 3 bool, any, any any
= assign to a variable or property right-to-left 2 lval, any any
*=, /+, %=, +=,
-=, &=, ^=, |=, <<=, >>=, >>>=
operate and assign right-to-left 2 lval, any any
, discard first operand, return second left-to-right 2 any, any any

based on

number of operands 

they expect

 

operators can be categorized as

 

unarybinaryternary
operators

unary operators

convert a single expression into a single more complex expression

i++ // post-increment operator

binary operators

combine two expressions into a single more complex expression

i - j // substract operator

ternary operators

combines three expressions into a single expression

JavaScript supports only the conditional operator

a ? 'a' : 'b'; // returns one of two expressions depending on the condition

operand & result type 

operators work with any type of values

BUT

some of them expect their operands to be of a specific type

&

most operators return a value of a specific type

operators usually convert the type of their operands as needed

'5' * '3'     //=> 15 

some operators

behave differently depending on the type of the

operands used with them

10 + 5              //=> 15
'Java' + 'Script'   //=> "JavaScript"
15 + 'px'           //=> "15px"

lvalue 
 

 lvalue is a historical term that means
“an expression that can legally appear
on the left side of an assignment expression

 

lvalues in JavaScript 

variables
properties of objects
elements of arrays

operators precedence 

controls the order in which operations are performed
operators with higher precedence are performed
before those with lower precedence

var a = 1 + 2 * 7      //=> 15  `*` has higher precedence than `+` and `=` 
                                 has the lowest precedence

operator precedence can be overridden

with the explicit use of parentheses

(1 + 2) * 7  //=> 21

property access & invocation expressions
have higher precedence

than any operator

operator associativity 

specifies the order in which operations of the same precedence

are performed

 

left-to-right associativity

operations are performed from left to right

30 - 10 - 5    //=> 15 -> is the same as ((30 - 10) - 5)

right-to-left associativity

operations are performed from left to right

var a, b, c;
a = b = c = 5;  //=> is equivalent to a = (b = (c = 5)) -> a, b, c all have the same value

order of evaluation

precedence & associativity
specify the order in which operations
are performed in a complex expression

BUT
they do not specify the order in

which the subexpressions are evaluated

 

JavaScript always evaluates expressions left-to-right

var a = b + c * d; // first the `a` is evaluated, then `b`, `c` & `d`
                   // then the values of `c` & `d` are multiplied, 
                   // added to the value of `b` and assigned to the
                   // variable or property specified by expression `a`

ARITHMETIC EXPRESSIONS

* multiplication operator
/ division operator
% modulo (reminder) operator
- substraction operator
+ addition operator

+ / - / ++ / -- unary operators
& /  |  / ^ /   /  <<  /  >>>>> bitwise operators

*  /   %   -

multiplication / division / modulo / substracion
 

evaluate their operands 

convert to numbers if necessary

perform arithmetic between values

5 * 3     //=> 15
15 / 3    //=> 5
15 % 2    //=> 1 -> 15 - (parseInt(15 / 2) * 2) 
          //     -> (1st_operand - (integer(1st_operand / 2nd_operand) * 2nd_operand)
30 - 15   //=> 15

non-numeric operands that cannot convert to numbers convert to NaN
&
the result of the operation will also be NaN

+

binary + operator

adds numeric or concatenates string operands

 

10 + 5                        //=> 15
"10" + "5"                    //=> "105"
"5" + 5 + 5                   //=> "555"
false + 15                    //=> 15
"15" + {}                     //=> "15[object Object]"
15 + undefined                //=> NaN
10 + 5 + " years old"         //=> "15 years old"
10 + (5 + " years old")       //=> "105 years old"

if one operand is string or an object that converts to a string
+ operator gives priority to string concatenation

unary operators

+  /  -  /  ++  /  --
 

they modify the value of a single operand

to produce a new value

 

all have
high precedence
are
right-associative

&
convert their operand to a number

 

unary plus +
 

converts its operand to a number (or to NaN)
&
returns that converted value

+"15"  //=> 15

if the operand is already a number it

does nothing

unary minus  -
 

converts its operand to a number
&
returns
the negation of its operand

-"15"  //=> -15

increment  ++
converts its operand to a number
adds 1

&
assigns the incremented value back

var count = 0;
console.log(count++);   //=> 0 - post-increment 
                        //       assigns the result of `count + 1` expression 
                        //       returns initial `count` value which is `0`

console.log(count);     //=> 1 - the `count` value is now `1`

console.log(++count);   //=> 2 - pre-increment
                        //       assigns the result of `count + 1` expression 
                        //       returns incremented `count` value which is `2`

console.log(count);     //=> 2 - the `count` value is now `2`

its operand must be a lvalue

decrement  -- 
converts its operand to a number
substracts 1

&
assigns the decremented value back

var count = 2;
console.log(count--);   //=> 2 - post-decrement 
                        //       assigns the result of `count - 1` expression 
                        //       returns initial `count` value which is `2`

console.log(count);     //=> 1 - the `count` value is now `1`

console.log(--count);   //=> 0 - pre-decrement
                        //       assigns the result of `count - 1` expression 
                        //       returns decremented `count` value which is `0`

console.log(count);     //=> 0 - the `count` value is now `0`

like ++ operator

its operand must be a lvalue

bitwise operators

perform low-level manipulation of the bits

in the binary representation of numbers

 

expect integer operands

&

behave as if those values were represented as 32-bit integers

rather than 64-bit floating-point values

bitwise AND  &
 

performs boolean AND on each bit of its integer arguments

15         //       32-bit -> 00000000000000000000000000001111
51         //       32-bit -> 00000000000000000000000000110011
           //                 --------------------------------
15 & 51    //=> 3   32-bit -> 00000000000000000000000000000011

 

X Y X & Y
0 0 0
0 1 0
1 0 0
1 1 1

 

AND operator's truth table is

bitwise OR  |
 

performs boolean OR on each bit of its integer arguments

15         //       32-bit -> 00000000000000000000000000001111
51         //       32-bit -> 00000000000000000000000000110011
           //                 --------------------------------
15 | 51    //=> 63  32-bit -> 00000000000000000000000000111111

 

X Y X | Y
0 0 0
0 1 1
1 0 1
1 1 1

 

OR operator's truth table is

bitwise XOR  ^
 

performs boolean  eXclusive OR  on each bit of its integer arguments

15         //       32-bit -> 00000000000000000000000000001111
51         //       32-bit -> 00000000000000000000000000110011
           //                 --------------------------------
15 ^ 51    //=> 60  32-bit -> 00000000000000000000000000111100

 

X Y X ^ Y
0 0 0
0 1 1
1 0 1
1 1 0

 

XOR operator's truth table is

bitwise NOT  ~
 

operates by reversing all bits in the integer operand

15         //       32-bit -> 00000000000000000000000000001111
           //                 --------------------------------
~15        //=> -16 32-bit -> 11111111111111111111111111110000

 

X ~X
0 1
1 0

 

NOT operator's truth table is

bitwise SHIFT LEFT  <<
 

moves all bits in its first operand to the left by the number of places
specified in the second operand

15        //                32-bit -> 00000000000000000000000000001111
-15       //                32-bit -> 11111111111111111111111111110001
          //                          --------------------------------
15 << 1   //=> 30           32-bit -> 00000000000000000000000000011110
15 << 15  //=> 491520       32-bit -> 00000000000001111000000000000000
15 << 31  //=> -2147483648  32-bit -> 10000000000000000000000000000000
-15 << 1  //=> -30          32-bit -> 11111111111111111111111111100010

bitwise SHIFT RIGHT WITH SIGN  >>
 

moves all bits in its first operand to the right by the number of
places specified in the second operand

15        //         32-bit -> 00000000000000000000000000001111
-15       //         32-bit -> 11111111111111111111111111110001
          //                   --------------------------------
15 >> 1   //=> 7     32-bit -> 00000000000000000000000000000111
15 >> 15  //=> 0     32-bit -> 00000000000000000000000000000000
-15 >> 15 //=> -1    32-bit -> 11111111111111111111111111111111

bitwise SHIFT RIGHT WITH ZERO FILL  >>> 
 

moves all bits in its first operand to the left by the number of places
specified in the second operand

15         //              32-bit -> 00000000000000000000000000001111
-15        //              32-bit -> 11111111111111111111111111110001
           //                   --------------------------------
15 >>> 1   //=> 7          32-bit -> 00000000000000000000000000000111
15 >>> 15  //=> 0          32-bit -> 00000000000000000000000000000000
-15 >>> 15 //=> 131071     32-bit -> 00000000000000011111111111111111

Relational Expressions

relational operators
test the relationship between two values

&

return true or false
depending on whether that relationship exists

 

they always evaluate to a boolean value

which is often used to control the flow

of the program execution

equality & inequality

==   /  ===
 

both operators check if two values are the same
both accept operands of any type
both return true if operands are the same
&
both return false if they are different

BUT

they use two different definisions of sameness

strict equality  ===
 

evaluates its operands and compares the two values

performing no type conversion

if the two values have different type  inequality
if both values are null or both undefined  equality
if both values are the boolean value true or both false  equality
if one or both values is NaN  inequality

if both values are numbers and have the same value  equality
if both values are strings and contain exactly the same 16-bit values in the same positions  equality

if both values refer to the same object array / function  equality
if values refer to different objects even if both objects have identical properties  
inequality

equality  ==
 

acts like strict equality but is less strict

in case values have the same type

it will test them for strict equality

 

in case values are not the same type

it attemps some type conversion

&

tries the comparsion again

if the values have different types

it will use the following rules

 

if one value is null & the other is undefined  equality
if one value is number & the other is string - convert string to number & compare again
either value is true - convert to number (1) & compare again
either value is false - convert to number (0) & compare again
if one value is an object & the other is number or string - convert object to a primitive & compare again
any other combination of values  inequality

"1" === 1             //=> false
null === undefined    //=> false
null === null         //=> true
1 === NaN             //=> false
NaN === NaN           //=> false
true === 1            //=> false
true === true         //=> true
false === 0           //=> false
false === false       //=> true
0 === -0              //=> true
0 === 0               //=> true

var obj1 = { prop: 1 }, 
    obj2 = { prop: 1 },
    obj3 = obj1;

obj1 === obj2         //=> false
obj1 === obj3         //=> true

"1" == 1              //=> true
true == 1             //=> true
false == 0            //=> true

var arr = [0];
arr == 1              //=> false
arr == 0              //=> true

strict inequality  !==
 

tests for the exact oposite of ===

 

it returns false if two values

are strictly equal to each other

returns true otherwise

inequality  !=
 

tests for the exact oposite of ==

 

it returns false if two values

are equal to each other according to ==

returns true otherwise

comparsion operators

<  /  > / <= / =>

 

test the relative order

(numerical or alphabetical)

of their two operands

less than  <
 

returns true if its first operand is less than its second operand

otherwise returns false

 

greater than  >
 

returns true if its first operand is greater than its second operand

otherwise returns false

 

less than or equal  <= 
 

returns true if its first operand is less than or equal to its second operand

otherwise returns false

 

greater than or equal  => 
 

returns true if its first operand is greater than or equal to its second operand

otherwise returns false

 

all of them support
operands of any type

BUT

comparison can be performed only on

numbers

&

strings

that's why operands that are not

numbers or strings are converted as follows

 

if either operand evaluates to an object it is converted to a primitive value
after conversion if both operands are strings 
the two strings are compared using alphabetical order
otherwise

if at least one operand is not a string
both operands are converted to numbers and compared numerically

 

0 & -0 are considered equal

Infinity / -Infinity are larger / smaller than any number other than itself

if either operator is or converts to NaN  false

in operator
expects a left-side operand that is or can be converted to a string and
a right-side operand that is an object
 

evaluates to true if the left-side value is the name of a property

of the right-side object & to false otherwise

var course = {
  title: 'JavaScript - The Basics',
  chapter: 'Expressions & Operators'
};

'title' in course      //=> true
'chapter' in course    //=> true
'page' in course       //=> false

var list = [ 'JavaScript - The Basics', 'Expressions & Operators', 'Page 57' ];

'0' in list  //=> true -> `list` array has an element on `0` index
1 in list    //=> true -> number is converted to string "1"
5 in list    //=> false -> `list` array doesn't have an element on `5` index

instanceof operator
expects a left-side operand that is an object and a right-side
operand that identifies a class of objects
 

evaluates to true if the left-side object

is an instance of the right-side class & to false otherwise

var obj = {},
    arr = [];

obj instanceof Object       //=> true -> `obj` is an object
arr instanceof Array        //=> true -> `obj` is an array
arr instanceof Object       //=> true -> all arrays are instances of `Object`

function Course() {}        //=> declaring a named function

var course = new Course();  //=> call it with the `new` keyword & assign to `course` variable

course instanceof Course    //=> true -> `course` is an instance of `Course` class
course instanceof Object    //=> true -> `Course` inherits from `Object`

LOGICAL Expressions

logical operators
&&
   /   ||   /   !

 

perform boolean algebra

are often used in conjunction with the relational operators
to combine two relational expressions into one 
more complex expression

logical AND  &&

if its operands are boolean values
it performs boolean AND on its operands
&
returns true only if both operands are true
otherwise it returns false

true && true           //=> true
false && true          //=> false
true && false          //=> false
false && false         //=> false

1 == [1] && 1 === 1    //=> true (1 == 1) && (1 === 1) 
                       //            |           |
                       //            V           V
                       //          true   &&    true

1 === [1] && 1 === 1   //=> ?

if its values are truthy / falsy values then it returns
a truthy value if both are truthy otherwise it returns a falsy value

it starts by evaluating its left operand
if this value is falsy the entire expression is falsy 
and left operand value is returned


if value is truthy the overall value of the expression 
depends on the value of the right operand whose value is the value returned

1 && 0         //=> 0
'' && 0        //=> ?
'XYZ' && 0     //=> ?
1 && '1'       //=> "1"
1 && 0         //=> 0
'' && 0        //=> ""
'XYZ' && 0     //=> 0
1 && '1'       //=> "1"

logical OR  || 

it performs boolean AND on its operands


if its operands are truthy falsy values

it returns a truthy value if either one of its operands is truthy

and returns a falsy value only if both are falsy values
 

it starts by evaluating the value of the left operand
if the value is truthy it will be the returned value
otherwise the right operand is evaluated whose value is the returned value

true || false  //=> true
1 || 0         //=> 1
'' || 0        //=> 0
'XYZ' || 0     //=> "XYZ"
1 || '1'       //=> "1"

logical NOT  !

​is a unary operator placed before a single operand
its purpose is to invert the boolean value of its operand

 

unlike && / || it converts its operand to a boolean value,

which means it always returns true or false

!true      //=> false
!""        //=> true
!!1        //=> true -> any value can be converted to its boolean equivalent
           //           by applying this operator twice

ASSIGNMENT Expressions

JavaScript uses the = operator

to assign a value to a variable or a property

var course = {};

course.title = 'JavaScript - The Basics';  // set the property `title` of object `course` 
                                           // to 'JavaScript - The Basics'

var count = 0;                             // set variable `count` to 0

its left-side operand is expected to be an lvalue
variable name  / object propertyarray element

 

the right-side operand is expected to be an arbitrary value of any type

assignament with operation

besides the normal = assignment operator

a number of other assignment operators
that provide shortcuts by combining assignment
with some other operation are supported


+= / -= / *= / /= / %= / <<= / >>= / >>>= / &= / |=  / ^=

var c = 10;

c += 1        //=> 11 -> `c` is 11   (c = c + 1)
c *= 2        //=> 22 -> `c` is 22   (c = c * 2)
c /= 4        //=> 5.5 -> `c` is 5.5 (c = c / 4)
c -= 0.5      //=> 5 -> `c` is 5     (c = c - 0.5) 
c %= 2        //=> 1 -> `c` is 1     (c = c % 2) 
c <<= 1       //=> 2 -> `c` is 2     (c = c <<= 1)
c >>= 1       //=> 1 -> `c` is 1     (c = c >>= 1)
c >>>= 1      //=> 0 -> `c` is 0     (c = c >>= 0)

EVALUATION Expressions

JavaScript

has the ability to interpret strings of JavaScript source code

this is done with the global function
 

eval()

eval("function sum(a, b) { return a + b; } sum(1, 1);")  //=> 2

eval() expects one argument
if other value than string is passed as argument
is will return that value

 

if a string is passed
it will attempt to parse it as JavaScript code
and returns the value of the last expression or statement

Special Operators

conditional operator  ? : 
 

it's the only ternary operator available in JavaScript

its operands may be of any type

 

first operand goes before the ?
and is evaluated and interpreted as a boolean
if the value is truthy then the second operand which goes
between ? and : is evaluated and its value gets returned

if the values of the first operand is falsy
the third operand which goes after : is evaluated and its value gets returned

1 ? "truthy" : "falsy"       //=> "truthy"
0 ? "truthy" : "falsy"       //=> "falsy"

typeof operator 
 

is a unary operator that is placed before its single operand


the operand can be of any type

its value is a a string that specifies the type of the operand

value typeof value
undefined "undefined"
null "object"
true or false "boolean"
any number or NaN "number"
any string "string"
any function "function"
delete remove a property
any nonfunction native object "object"
any host object An implementation-defined string, but not “undefined”, “boolean”, “number”, or “string”

delete operator 
 

is a unary operator that attempts to delete the object
property or array element specified as its operand

a deleted property or array element is not set to the undefined value
when a property is deleted the property ceases to exist

var course = {
  title: 'JavaScript - The Basics',
  chapter: 'Expressions & Operators'
};

delete course.chapter
'chapter' in course    //=> false


var list = [ 'JavaScript - The Basics', 'Expressions & Operators', 'Page 57' ];

delete list[0]
'0' in list  //=> false

void operator 
 

is a unary operator that appears before its single operand
which may be of any type

it evaluates its operand
then discards the value and returns undefined

var sum = function (a, b) {
  return a + b;
}

void sum(1, 2);               //=> undefined

void operator is commonly used in 
browser javascript:URI

<a href="javascript:void(0)">Click here</a>

the browser evaluates the code in the URI
then replaces the contents of the page with the returned value
unless the returned value is undefined

comma operator ,
 

is a binary operator whose operands may be of any type

it evaluates the left operand
then evaluates the right operand and returns its value

var a, b, c;

a = 0, b = 1, c = 2;   //=> 2

// is the same as
a = 0;
b = 1;
c = 2;

JavaScript - The Basics - Expressions & Operators - Part III

By Raul Matei

JavaScript - The Basics - Expressions & Operators - Part III

  • 1,349