All Types All the Time
In this set of slides, we'll take a look at:
- JavaScript's types
Numbers
and numeric operatorsStrings
and string operatorsBooleans
and logical and comparison operatorsundefined
andnull
Some Definitions
- value - data
- type - a category or classification of values
- operator - a language construct that allows the manipulation or combination of a value or values to yield another value
- operand - a value that an operator works on; the subject of an operator
- unary operator - an operator that only has one operand
- binary operator - an operator that has two operands
- prefix operator - an operator that goes before (to the left) of its operand(s)
- infix operator - an operator that goes between its operands
typeof
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….
TELL ME ABOUT THE TYPES!
Seriously, stop messing around. Types Really:
- Undefined -
typeof
returnsundefined
- Null -
typeof
returnsobject
because JavaScript is terrible (or to maintain backwards compatibility with previous versions of JavaScript) - Boolean -
typeof
returnsboolean
- String -
typeof
returnsstring
- Number -
typeof
returnsnumber
- Object -
typeof
returnsobject
- Symbol -
typeof
returnssymbol
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.
Primitives vs Objects
Hey… those two terms should sound familiar… →
- booleans, numbers, strings,
null
andundefined
are primitive values:- they're immutable
- they're compared by value
- note that wrapper objects for primitives do exist (we'll see this later)
- objects, on the other hand:
- are compared by reference
console.log({} === {}) // false! const foo = {}; const bar = foo; console.log(foo === bar); // true (because "aliasing")
- are mutable (by default, though they can be made immutable-ish)
More About Numbers
- So how many values can 64 bits hold? (Um… a lot?) →
- 2 to the power of 64! About 18 with 18 0's after it. However, this doesn't exactly indicate what numbers can be stored. Why? →
- This just means that number of possible values. This has to include negative numbers, decimals, etc…
Some Special Numbers…
Try the following operations… →
0/0
9e300 * 25874481
- JavaScript has some special number values:
- NaN (Not a Number) - this results from any numeric operation that doesn't give back a meaningful result…
- Infinity, -Infintity - positive and negative infinities
- Note that these special values are actually numbers! (really!)
- that is, both
NaN
and Positive/NegativeInfinity
are of typeNumber
! →typeof NaN // --> number (what??? ok) typeof Infinity // --> number
- that is, both
More About NaN
Again, NaN stands for not a number
NaN
is toxic …- using it in any other numeric operations always results in NaN →
NaN + 1
→NaN
- the only way to check if a value is
NaN
is by using the built-in functionisNaN(val)
- oddly,
NaN === NaN
isfalse
(!? … as specified by IEEE)
More About Infinity
So, there's Infinity and -Infinity
- Infinity
+ 1
or Infinity+
Infinity→ is stillInfinity
Infinity
represents all values greater than 1.79769313486231570e+308- dividing by 0 yields
infinity
- equality operators and the global function
isFinite
can be used to determine if a value isInfinity
Strings Continued
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: ""
String Operators
A few string operators:
- string concatenation, or +, is an operator that takes two strings and joins them:
"hello " + "there"
- indexing, or []… can be used to retrieve the character at an index, such as
'emoji'[3]
(or usecharAt
) - comparison operators, you can use
<
,<=
, etc. … unicode code points are compared'B' > 'A' // true
Booleans
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
Inherent Truthiness
When non-boolean types are converted to booleans, the followings rules are used →
0
,NaN
, empty string (""
), andundefined/null
are false- other values are true-ish
Let'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!");
}
Logical Operators
Boolean values can be combined and manipulated using logical operators. What are some logical operators, and what do they do? →
- and - && - returns true if and only if both operands are true, otherwise, returns false
- or - || - returns false if and only if both operands are false, otherwise, returns true
- not - ! - returns the opposite boolean value of its single operand to the right
And and Or With Non Boolean Values
Some details about &&
and ||
:
- if operands are not actually boolean, convert the value on the left side to a boolean
||
- will return the left operand's value if it's true
- otherwise, return the value on the right
- can be used as a way to fall back to a default value
potentially_falsey || default_value
&&
- will return the left operand's value if it's false
- otherwise, return the value on the right
- also… short-circuit evaluation applies
And and Or Continued
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"
Ternary Operator
What will this code return?
true ? "ok" : "not ok!"
- "ok"
- format is
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';
}
Comparison Operators
Booleans can be produced from comparison operators. Without knowing anything about JavaScript, what do you think are some available comparison operators? →
- <, >, <=, >= - greater than, less than, etc.
- === - equals, checks both type and value
- !== - not equals, checks both type and value
- == - equals, coerces operands to appropriate types
- != - not equals, coerces operands
Comparison Operators Continued
Comparison Operators are binary , infix operators that can be used to compare two operands:
- numbers are obvious:
5 > 2
→ - strings are compared from left to right (by character code):
"aardvark" > "bison"
(more or less, alphabetic) → - NaN is the only value not equal to itself →
- You'll probably always want to use === →
undefined
and null
See the section on undefined and null in our book
- undefined means no value
- think of a function that doesn't return a value
- or the value of a declared variable that hasn't been given a value yet
- or a missing argument to a function
- null means "no object"… it's a value that can be assigned to a variable to represent "no object" →
- the subtle differences between
undefined
andnull
are an accident of language design!- you'll typically find
undefined
when something wasn't initialized - you'll find
null
if an object is explicitly set tonull
- you'll typically find
Type Coercion
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!
Type Coercion With Numeric Operators
- for addition:
- when one operand is a string and the other is not, the other operand is converted into a string, and the two strings are concatenated
- for all other cases, the operands are converted to numbers
- true → 1
- false → 0
- null → 0
- undefined is still undefined, and result gives back NaN
- for other numeric operators, such as subtraction:
- will usually try to convert to number
- if something cannot be converted easily (like the string, "hello"), the result is
NaN
Type Coercion With Equality Operators
- JavaScript will do its best to convert types so that they can be checked for equality - these all return true →
"10" == 10
0 == false
"" == false
- this is Usually an unwanted behavior; to avoid this, use: === and !==
- these operators check type and value
- use these three-character comparison operators to prevent unexpected type conversions
If you want to see the details for every possible operand combination for double equals, check out mdn's table