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

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;  //=> 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

JavaScript - The Basics - Expressions & Operators - Part II

By Raul Matei

JavaScript - The Basics - Expressions & Operators - Part II

  • 1,181