Important notes

In this course we've been comparing things using three equal signs:

a === b;
12 === 12;

This comparison is strict: are those two things precisely the same?

There is a relaxed comparison in JavaScript — with to equal signs. It shows you what happens in JavaScript's mind when it deals with types:

1 === '1';    // false
1 == '1';     // true

true === 1;   // false
true == 1;    // true

Lesson notes

Types in JavaScript

JavaScript has a notion of types: numbers, strings, functions, boolean, etc. typeof returns a string indicating the type:

typeof 42;      // 'number'
typeof 3.14;    // 'number'
typeof NaN;     // 'number'

typeof 'Berry'; // 'string'
typeof true;    // 'boolean'
typeof false;   // 'boolean'

NaN means "not a number", but the type of this value is number.

A variable without a value has a special value undefined. Type of this variable is undefined:

let a;
console.log(a);   // undefined
typeof a;         // 'undefined'

Dynamic vs Static typing

The code you write is usually converted into some other form that a computer knows how to run. This process is called compilation, and the period of time this happens is called "compile time".

After compilation is over, the program is launched, and the period it's running is called "runtime".

Statically typed languages check the types and look for type errors during compile time.

Dynamically typed languages check the types and look for type errors during runtime.

Another way to think about it: static typing means checking the types before running the program; dynamic typing means checking the types while running the program.

Weak vs Strong typing

JavaScript assumes and converts types automatically a lot:

4 + '7';      // '47'
4 * '7';      // 28
2 + true;     // 3
false - 3;    // -3

JavaScript is a weakly typed language. It has a notion of types, but it's relaxed about them, and can treat values somewhat arbitrary. The stronger the typing system is — the stricter the rules are.

Explicit conversions in JavaScript

Number('590');    // 590
Number('aaa!!');  // NaN

Boolean(1);       // true
Boolean(0);       // false

String(true);     // 'true'
String(false);    // 'false'

String('44843');  // '44843'

Optional reading

Fun


Lesson transcript

Few lessons ago we were talking about errors and how to deal with them. There are different kinds of errors, and I want you to recall one particular kind. Here is a little piece of that lesson:

===========

The next kind of error is when you confuse one thing for another. Look at this code:

const length = 12;
const num = length(54);

First, we create a constant. Remember, it's like giving a name to something, in this case — giving a name length to a number 12. Then, on the second line, we call a function length and pass an argument — number 54. But wait! length is not a function! It's a number. Numbers are not functions, not boxes that do stuff. And this is exactly how JavaScript will complain:

→ node test.js
/Users/rakhim/test.js:2
const num = length(-54);
            ^

TypeError: length is not a function
    at Object.<anonymous> (/Users/rakhim/test.js:2:13)
    at Module._compile (module.js:571:32)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:488:32)
    at tryModuleLoad (module.js:447:12)
    at Function.Module._load (module.js:439:3)
    at Module.runMain (module.js:605:10)
    at run (bootstrap_node.js:420:7)
    at startup (bootstrap_node.js:139:9)
    at bootstrap_node.js:535:3

This is a Type Error — the type of the thing you've used is wrong. JavaScript interpreter wouldn't tell you what the thing is, but it will tell you what it isn't. length is not a function.

Type Error is like asking your cat to do the laundry. You probably wanted to ask your roommate.

==============================

In programming "type" is a classification of information. This is a general term, and different programming languages deal with types in different ways. As you know by now, JavaScript somehow can see the difference between types. Function is one type, Number is another type, and you can't just use a number as a function.

typeof is a special operator that returns a string indicating the type.

typeof 42;      // 'number'
typeof 3.14;    // 'number'
typeof NaN;     // 'number'

typeof 'Berry'; // 'string'
typeof true;    // 'boolean'
typeof false;   // 'boolean'

42 and 3.14 are obviously numbers, some combination of letters in quotation marks is a string, and true and false are boolean. These are some of the types in JavaScript — number, string, boolean.

NaN means "not a number", but the type of NaN is "number". Yeah, I know. Another JavaScript weirdness. Those are the rules of this language.

Types are helpful. When we've tried running a number as if it was a function, JavaScript started complaining and we could see the problem and fix it. If there wasn't any notion of types in JavaScript, we would either see some bizarre unexpected behavior or some mystic error. Instead of clear "length is not a function" we'd have something like "I'm sorry Dave, I'm afraid I can't do that".

What if you create a variable, but don't give it any value? What type would that be? It's not a number, not a string, not... anything. Because there is no value, right?

JavaScript does something behind your back in this case. The variable without a value actually has a special value — 'undefined'. And the type of this variable is called 'undefined'.

let a;
console.log(a);   // undefined
typeof a;         // 'undefined'

So, for example, type number has lots of potential values: 1, 2, -10, 69000, and other numbers. But type undefined has only one value — undefined.

There are two important things to understand when it comes to types in programming: dynamics vs static and weak vs strong.

In order to understand the difference between dynamic and static typing, we first have to look at how written programs become actual running programs.

The code you write is usually converted into some other form that a computer knows how to run. This process is called compilation, and the period of time this happens is called "compile time".

After compilation is over, the program is launched, and the period it's running is called "runtime".

Some languages check the types and look for type errors during compile time. Those have static typing.

Other languages check the types and look for type errors during runtime. Those have dynamic typing.

Another way to think about it: static typing means checking the types before running the program, dynamic typing means checking the types while running the program.

C#, C++, Java, Go are statically typed languages. If you create a number and try to treat it as a function in one of those languages, you'll get an error during compilation, and your program will not even try to run — it won't get to that point because a type error would've been found before runtime, at compile time.

JavaScript, Ruby, PHP are dynamically typed languages. As you've seen before, if use the incorrect type, your program does run, and the error occurs only when that particular line of code is executed. So, the types are checked during runtime.

Actually, JavaScript usually doesn't have any compilation at all, but that's a topic for another lesson.

Dynamic typing is not worse or better than static typing. Both ways have advantages and disadvantages. Dynamically typed languages are usually easier to learn and to write programs in, but, as you can imagine, it leads to more mistakes and bugs.

Now let's talk about weak and strong typing. Check out this JavaScript code:

4 + '7';      // '47'
4 * '7';      // 28
2 + true;     // 3
false - 3;    // -3

Yeah... This is... Okay, what's going on? Adding number 4 to a string '7' gives us a string '47'. JavaScript converted number 4 into a string '4' and concatenated two strings — glued them together. JavaScript just took the liberty of assuming this is what we wanted. It's hard to blame it — what did we want? Adding a number to a string — that doesn't make sense. Some other language, like Ruby or Python would've just complained and not do anything.

Multiplying number 4 by a string '7' is, well, 28, according to JavaScript. In this case, it converted string '7' into number 7 and did the normal multiplication.

JavaScript does this a lot. It knows about the types of different values but when types don't match, it tries to assume and convert from type to type without telling you. Sometimes it's useful, sometimes it's mindboggling. This happens because JavaScript is a weakly typed language. It has the notion of types, but it's like, "it's only a game, why you have to be mad?"

This has nothing to do with dynamic versus static typing, which is about WHEN to check for types. Strong versus weak is about HOW SERIOUS DO YOU GET while checking the types.

You can say that weak typing is relaxed typing, and strong typing is strict typing.

Unlike dynamic vs static, the strength of the typing system is a spectrum. JavaScript has very weak typing. PHP has somewhat stronger typing. Python — even stronger. And all three are dynamically typed languages.

So, JavaScript does a lot of implicit conversions, but it also gives us tools to do explicit conversion ourselves. We can convert strings to numbers and numbers to strings, boolean to string etc like this:

Number('590');    // 590
Number('aaa!!');  // NaN

Boolean(1);       // true
Boolean(0);       // false

String(true);     // 'true'
String(false);    // 'false'

String('44843');  // '44843'

You can probably guess that implicit type conversion is not the best idea ever. Implicit means hidden, and hidden means it's hard to understand and easy to make mistakes. The behavior of the program becomes less obvious. You write less code, yes, but the code is more fragile and less understandable.