1. Strings are definitely strings right? Well… kind of:
You’ve probably heard that in Javascript “everything’s an object” right? In fact strings are both objects and strings at the same time:
Javascript hot swaps the 'my string'
literal value for an object every time you want to access the string’s prototype properties, like length
, but when you want 'my string'
it uses the string literal value instead.
2. The difference between expected arguments and actual arguments:
The Function.length
property can tell you how many arguments a function expects but because JS lets you give a function as many arguments you want (again, weird) you can access the special arguments
object to find out how many args it’s actually been given.
You might think the spread operator is sugar coating for the same thing…
…but it’s not. lolz.
arguments
isn’t made from the array prototype, even though it still has a length
prop.
arguments
is also useful for calling a function from inside itself without having to know the function’s name.
3. These are the same thing:
You might have tried using typeof
on an array and found that it says it’s an object:
…which it is…because almost everything in JS is an object. What you really want to know is, what was this object constructed from.
Checking the constructor is a bit more reliable, which is actually what instanceof
is doing under the hood:
So what does this next snippet do?
The constructor
isn’t effected by the array object it’s nested in. So arr.constructor()
will make a new empty array:
Just like doing new Array()
.
4. Making arrays full of undefined
You can fill arrays with undefined by simply putting commas in them:
How many undefined
items do you think this has? Surely 4 right? One for each space between commas. That would make it the same as the number of commas you’d use for [undefined, undefined, undefined, undefined]
.
Nope, it’s actually one for each comma!? That’s three undefined’s lol, ok.
You can also make an array with three undefined
’s using new Array(3)
. What’s weird about Array
is that if you give it more args they’ll fill the array…
So the first argument does something different depending on how may arguments are passed in. Seriously?
5. Arrays are objects, I know you already know this but…
..try using one like an object.
I mean, this is kind of obvious when you think about it, but it’s weird to look at if you’re used to thinking of arrays as their own type.
An array is really just a number-indexed object. The only difference is, if it’s constructed from Array
your log will get little []
brackets and it’ll hide the indexes.
We see: [true, true, true]
.
But really it looks like: {0: true, 1: true, 2: true}
.
6. Array-like Objects
Just as an array can be used like an object, an object can be used like an array:
We’d call this object “array-like” because it has a length
and indexes but it wasn’t constructed from Array
. The arguments
object from the earlier example is an array-like object.
7. The this Keyword in Nested Functions
You probably know that this
refers to the global object in a function and in a method it refers to the object it belongs to:
Makes sense right? this
always refers to the object the function is declared in and myFunc
is declared in the global scope.
But this is actually not true. Only methods behave in this way. When this
is used in a function declaration it always refers to the global object, even if it’s declared inside a method!
This is one of the reasons function expressions are useful…
Function expressions cause this
to be the same as scope they’re declared in.
8. Function Properties
Functions are objects, no duh, you definitely know this by now. You can add properties to them if you want and they have properties already, like length
, name
and caller
.
So if I make a function I can add things to it and access them using the arguments.callee
property…
But you can also add the prop before declaring the function:
This works because function statements are hoisted meaning javascript pulls them out of the code and defines them before anything else.
Function literals and function expressions aren’t hoisted so these will all break…
But in the first example myFunc
has already been declared so we can add whatever we want to it.
9. Functions don’t need to be named when…
…they’re added to arrays:
…returned from functions:
…assigned to variables:
…when they’re expressed:
10. Function scope is confusing
I mean, you almost definitely know that right, but do you know what scope this
refers to in each of the following functions:
myFunc
— refers to myObj
, because object methods always refer to their object.
myNestedFunc
— refers to myObj
because fat-arrow functions always keep the scope of the place they’re created.
mySuperNestedFunc
— refers to the global scope!
When a function is declared it’s this
always refers to the global scope.
That’s it for now!
The JS chads out there might have noticed these tips roughly follow the structure of Javascript The Definitive Guide.
I’ve been going through it and adding anything I found surprising into here for the past few months (I’m a slow reader and it’s a big book!).
Let me know if these tips where useful in the comments and I’ll carry on doing articles like this one, it helps me to write down things when learning new things so it’s beneficial for me as well.