In this set of slides, we'll take a look at:
Numbers
and numeric operatorsStrings
and string operatorsBooleans
and logical and comparison operatorsundefined
and null
Yup Similar to comments in C or Java…
// a comment
/*
a multiline
comment
*/
317.0
"oh, hello"
true
{'name': 'Joe'}
function() {console.log("in here!")}
undefined
Based on the values in the previous slides, guess what types JavaScript supports? →
Actually… these are the types that the typeof
operator returns… the specs specify something different (we'll see in a minute)
Before we delve into these data types, let's check out a unary, prefix operator:
typeof
As you might expect, typeof
returns a string that represents the operand's type:
> typeof 317.0
'number'
We'll be using typeof
extensively for the next few slides….
The ECMAScript specification lists some types, but they're not the ones that typeof returns (of course!)
Undefined
Null
Boolean
String
Number
Object
Symbol
(ES6)
Wait… what? Then what's typeof
doing?
typeof
Do?Weelllll…. it behaves exactly according to what's specified:
typeof undefined → "undefined"
typeof null → "object"
???typeof false → "boolean"
typeof 5 → "number"
typeof 'foo' → "string"
typeof console.log → "function"
typeof [1, 2, 3, 4] → "object"
???
Seems like null
is an object (!? … a mistake?). Array
is also listed as a generic object. ¯\(ツ)/¯.
typeof
returns undefined
typeof
returns object
because JavaScript is terrible (or to maintain backwards compatibility with previous versions of JavaScript)typeof
returns boolean
typeof
returns string
typeof
returns number
typeof
returns object
typeof
returns symbol
Functions are actually just objects, but typeof
gives back function
when its operand is a function. Arrays are objects too, so typeof
returns object
for an Array.
Hey… those two terms should sound familiar… →
null
and undefined
are primitive values:
console.log({} === {}) // false!
const foo = {};
const bar = foo;
console.log(foo === bar); // true (because "aliasing")
123 // an integer - just digits
12.3 // a floating point number - decimal point
12e3 // (12 times 10 to the 3rd) exponent
> Math.pow(2,53)
> 9007199254740992
9007199254740992
> 9007199254740993
9007199254740992
0.1 + 0.2 // ????
→0.1 + 0.2 === 0.3 // false!?
Math.abs((0.1 + 0.2) - 0.3) < 0.0000000000000004 // true!
A quick list of binary, infix arithmetic operators (they take two operands, one on each side of the operator):
What order would I evaluate this in? What is the resulting value? →
4 + 1 * 5
// force addition first
(4 + 1) * 5
A couple more operators - these are prefix, unary operators that yield numbers:
+12
-12
-"12"
+"12"
-true
Note that they work on non-number types as well! These operators can be used to convert strings to numbers.
What do you think the following operators do? →
2 & 3 // 10 & 11 = 10 = 2
7 ^ 3 // 111 ^ 011 = 100 = 4
Note… bitwise operators work in 32 bits (even though numbers are stored in 64)
let's try these →
What do you think the following operators do? →
2 << 3 // 10 << 11 = 10000 = 16
What are the results of the following expressions? →
8 | 2 // 1000 | 0010
8 >> 2 // 1000 >> 0010
10
2
Try the following operations… →
0/0
9e300 * 25874481
NaN
and Positive/Negative Infinity
are of type Number
! →
typeof NaN // --> number (what??? ok)
typeof Infinity // --> number
Again, NaN stands for not a number
NaN
is toxic …NaN + 1
→ NaN
NaN
is by using the built-in function isNaN(val)
NaN === NaN
is false
(!? … as specified by IEEE)So, there's Infinity and -Infinity
+ 1
or Infinity +
Infinity→ is still Infinity
Infinity
represents all values greater than 1.79769313486231570e+308infinity
isFinite
can be used to determine if a value is Infinity
For bitwise operators… Nan
, Infinity
, and -Infinity
are all converted to 0 →
NaN | 2 // evaluates to 2
Infinity & 10 // evaluates to 0
Also… there is definitely a binary representation for these special numbers (Nan
, Infinity
, and -Infinity
)… the closest I came to determining it was here
A string is an ordered sequence of Unicode characters (what's Unicode? →). You can tell that a value is a string if it is surrounded by single or double quotes:
'I am a string'
"I'm a string too!"
A string can be composed of any characters: numbers, letters, punctuation, spaces, etc.
The following is a string with nothing in it… or an empty string:
""
If there is a backslash in a string (\), that means:
For example, \n is a newline and \t is a tab
"\n"
"\t"
How would we put a double quote in a double quoted string? →
"\""
And what about an actual backslash? →
"\\"
You can specify characters by using their unicode code point!
\u
How does that work? Welll…. →
console.log('\u0041')
- 65 - uppercase AA few string operators:
"hello " + "there"
'emoji'[3]
(or use charAt
)<
, <=
, etc. … unicode code points are compared 'B' > 'A' // true
If you want multiline strings or string interpolation, use template literal syntax:
${variableName}
to output the value of a variable in a string
const s1 = `such
lines
wow`;
const food1 = 'bacon';
const food2 = 'pancakes';
const s2 = `Makin' ${food2}, makin' ${food1} ${food2}!`;
console.log(s1)
console.log(s2);
A boolean is a data type that has two possible values: true
or false
.
As one would expect, the literals for these values are (all lowercase):
true
false
When non-boolean types are converted to booleans, the followings rules are used →
0
, NaN
, empty string (""
), and undefined/null
are falseLet's test this out… →
// outputs "in here"
if("this string says false, but...!?") {
console.log("in here!");
}
// no output
var myString = "";
if(myString) {
console.log("you shouldn't see me!");
}
Boolean values can be combined and manipulated using logical operators. What are some logical operators, and what do they do? →
What do the following boolean expressions return?
false && true
false || true
false || !true
false
true
false
The operator precedence for logical operators is not, and, and or.
Some details about &&
and ||
:
||
potentially_falsey || default_value
&&
Based on the previous slide, what are the values produced by the following expressions? →
5 - 5 || 2
5 - 5 && 2
"hello" || "goodbye"
"hello" && "goodbye"
2
0
hello
goodbye
This syntax is actually sometimes used to assign a default value if a value doesn't exist:
// we haven't seen objects yet, but you get the idea
const obj = {prop1: "a value"};
const val1 = obj.prop1 || "default value"
const val2 = obj.prop2 || "default value"
What will this code return?
true ? "ok" : "not ok!"
test
(boolean expression) ? value
to return if true : value
to return if false
The ternary operator works like an if/else statement, but it's one line and it evaluates to a value:
// ternary followed by equivalent if/else
let x = 5 > 2 ? 'yes' : 'no';
let x;
if(5 > 2) {
x = 'yes';
} else {
x = 'no';
}
Booleans can be produced from comparison operators. Without knowing anything about JavaScript, what do you think are some available comparison operators? →
Comparison Operators are binary , infix operators that can be used to compare two operands:
5 > 2
→"aardvark" > "bison"
(more or less, alphabetic) →undefined
and null
See the section on undefined and null in our book
undefined
and null
are an accident of language design!
undefined
when something wasn't initializednull
if an object is explicitly set to null
What values would you expect from the following lines of code? →
5 + 5
"5" + 5
"five" + 5
5 == "5"
5 === "5"
5 * undefined
5 * null
10
'55'
'five5'
true
false
NaN
0
How do we know? We can read the ECMAScript specifications!
NaN
"10" == 10
0 == false
"" == false
If you want to see the details for every possible operand combination for double equals, check out mdn's table 👀
For relational / ordering operators like >, <, etc. →
What the what????
+-12
-+12
+"hello"
These expressions evaluate to…
-12
-12
NaN
From the docs on mdn…
NaN
)
The order of operations is innermost prefix operator first (right to left).
…Without having to remember a series of obscure rules →
===
(we've gone over this before!)We can use object contructors as functions to cast to a type:
new
to convert to that typenew
with your constructor (avoid!)…
// do this (call constructor named after type as a function)
i = Number("2")
a = Boolean(false);
// not this (not a good idea to use new!)
b = new Boolean(false);
// because
console.log(typeof a); // --> boolean
console.log(typeof b); // --> object
// ... and 😒
Boolean(new Boolean(false)) // True!?
Another option is to use some of the operators that we learned to coax JavaScript into doing a predictable automatic conversion for us:
!!"hello"
+
+"5"
, +"hello"
parseInt
5 + ""
For mind boggling detail, see You Don't Know JS on coercion.
Undefined (and also null) means the absence of a meaningful value.
How would you check if a value is undefined? The two ways to do this are: →
if (myVar === undefined)
if (typeof myVar === 'undefined')
Use the isNaN function to determine if a value is not a number.
(comparing NaN to itself always yields false) →
NaN == NaN
NaN === NaN
// false
// false
// weird, eh?
Remember… NaN is not ordered with any value!. Use isNaN
…
isNaN(NaN)
The previous material in this set of slides are about general best practices. Not adhering to them may:
The next few suggestions, however, are purely stylistic - just about how code is formatted: →
if (some_boolean_expression) { // <-- curly brace here!
// do stuff
}
myVerboseVariableName
Number
, Boolean
, etc.)!!
, +
, + ""
if(typeof myVar == 'undefined')
isNan(myVar)
All of those operators! What goes first again!? (Check out operators precedence here.)
A quick summary:
Name 6 types (as given by typeof) that we know in JavaScript and a literal example of each. →
317
"yup, a string"
true
function f(x) {return x * 2}
{'classSection': '002'}
undefined
(of course!)We talked about a bunch of operators. The following are categories of operators, give examples of each →.
+ - * / %
& | ^ ~ < > >>
&& || !
== != === !== > < >= <=
+
and -
… convert to positive or negative numbertypeof
… obvs, returns string representation of type of operand++
and --
… increment and decrement