JavaScript — The weird parts

A journey through some language oddities

In this post I’d like to recap some of the things we talked about at the January YYCJS meetup. It was all about the weird parts of JavaScript. You can find the video on Youtube, the slides at yycjs.com/the-weird-parts and the live-coding parts on JSBin.

Many thanks to @alexisabril for sanity checking and Assembly (the fantastic host of the meetup) for the image. Also, check out this blog post by Minko Gechev (with the same title) talking about some other weirdnesses.

Warm Up

To get into the mood we talked about objects and that object properties can either be accessed using the . (dot) or [] (square brackets) operator where the dot operator only accepts valid JavaScript variable names and the square brackets can take any string:

There is no real difference between using single or double quotes for strings except which character you’ll have to escape. As always it makes sense to be consistent and there seems to be a general preference towards single quotes (less keys to press on most keyboards).

Function arguments

In a function arguments is a special array-like variable that contains all parameters passed to it:

Using arguments is often used to emulate function overloading when a function is called with a different number of parameters.

arguments is not a real array, it is only an array-like object with a length property and indices. If you want to use array methods like push or pop, you can convert it using jQuery.toArray() or like this:

Truthy- and falsyness

In JavaScript, values other than actual booleans can evaluate as true (truthy) or false (falsy) in a logical expression. The following values will be treated as falsy:

They can, for example, be evaluated in an if statement:

Note: This does not work for undeclared variable names. If you want to see if a variable exists (and is not undefined) use the typeof operator:

The result of a logical expression is not always a real boolean. Using || (or) will return the first truthy or last value in the expression. This is often used for assigning default values to an object or for default parameters in a function:

Note: I recommend only reassigning function argument variables for setting defaults and use a local variable if it will change in any other way.

Equality

Just on the heels of truthy and falsyness is equality comparison. The basic == (equal) and != (not equal) operators only compare the value (without the type), for example:

The === (triple equal) and !== (not triple equal?) operators compare value and type:

Objects are always compared by their reference so the expression will only be true if it is actually the same object:

For consistency and to avoid very hard to find bugs always use === and !==. Sometimes this might mean more code to write (like converting strings if you expect a number) but it will make things a lot easier and more predictable.

Scope

JavaScript only knows function scope. This means that blocks or for and while loops do not introduce a new variable scope effectively making it the same as declaring every variable at the beginning of the function.

Functions within other functions can access variables from their parent scope (closure) but not the other way.

Sometimes you might see all variables being declared at the beginning of the function. This is mainly a style question and not necessary if variable names are kept descriptive and functions are kept small.

Closures

Lets look at the following jQuery code snippet that creates ten buttons, adds a click handler and appends them to the body.

Clicking any button however will not alert this buttons number as you would expect but the number 10 for every button instead.

The reason is again variable scope. The click handler function accesses the the same variable from its parent and since it always gets executed after the loop is done, it will have the same value everywhere.

The trick here is to introduce a new scope through a wrapper function and call it with the current count. It will then be copied into a new variable counter:

Only primitive values (string, boolean, number) will be copied. If you pass an object you will get the same object reference which is important to know if you intend to modify that object.

Global variables

In browser environment, variables declared without var will automatically become global, in Node they will be global to the module:

This is probably always unintentional. A good way to avoid accidental global variable leaks in Node and newer Browsers is to enable ECMAScript 5 strict mode with

at the beginning of a function or JavaScript file. A global variable leak will then throw a ReferenceError.

If you do need global variable, add and access them through the global object (window in the Browser, global in Node) explicitly:

What is this?

In any function, this is a reserved keyword that refers to the owner of the function. For example when calling a function defined on an object, it will be the object itself:

this is also used in event handler functions, where it refers to the element(s) that triggered the event:

The trinity of this

Being able to change the owner of a function can lead to some confusion what this currently refers to but there are only three rules for what it can be:

  1. The object, when the function is called on the object (using the . or [] operator)
  2. The new object when a function is called with the new operator
  3. The owner has been set with call, apply or bind

Otherwise this will be the global object or undefined in strict mode:

this and callbacks

Callbacks are used for any kind of asynchronous operations. A common pitfall is to forget that in any new callback you will probably lose the original this. To keep the reference you will need to store it in a new variable so that it can be referenced (through its closure):

Conclusion

This is a definitely incomplete list of some JavaScript weirdnesses and things you might trip over especially when just starting out with JavaScript. In a follow up post I want to talk about inheritance in JavaScript (which was also covered in the meetup).

I make open source @feathersjs and decentralize things @bidalihq

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store