Most of my development experience has been with C#. When I started learning JavaScript, I made a few poor assumptions about the language. My incorrect assumptions about JavaScript inspired this list of three JavaScript gotchas for the C# developer:
- Brackets do not define scope.
this
does not refer to an instance of a class.- Function overloading doesn’t work quite like you’d expect it to.
A quick disclaimer. I orignally created this list of gotchas prior to learning ES2015.
Brackets do not define scope
In C#, defining new scope is as simple as enclosing code within braces (block scoping). In JavaScript, scope is not defined by braces. Scope is defined by functions. Consider the following snippet:
function sum(numbers) { var sum = 0; for (var x = 0; x < numbers.length; x++) { sum += numbers[x]; } console.log(x); // prints numbers.length - 1 return sum; }
It is legal to access the variable x
after the for loop. JavaScript uses a mechanism known as hoisting for its functions and variables. Declarations are hoisted or moved to the top of the function or global code. In our case, the variable x
is hoisted to the top of the function. The actual snippet runs like this:
function sum(numbers) { var sum = 0; var x; for (x = 0; x < numbers.length; x++) { sum += numbers[x]; } return sum; }
ES2015 introduced the keywords let
and const
. Unlike variables declared with var
, let
and const
variables have block scope. Variables declared with let
and const
are still hoisted, but the variables are hoisted to the top of the block versus to the top of the function.
If we rewrote our sum
function with let, accessing the variable x
after the for loop would result in a ReferenceError
.
function sum(numbers) { let sum = 0; for (let x = 0; x < numbers.length; x++) { sum += numbers[x]; } console.log(x); // ReferenceError: x is not defined return sum; }
An update:
I learned something new related to scoping in JavaScript: variables declared with var
in the catch
block of a try/catch
statement have block scope.
For a more thorough explaination of scope in JavaScript, check out Kyle Simpson’s book You Don’t Know JS: Scope & Closures.
this
does not refer to an instance of a class
In C#, the this
keyword returns the current instance of a class. In JavaScript, this
behaves a bit differently. If you access this
outside of a function, this
refers to the global object. If you access this
within a function the this
keyword references the caller of the function.
Let’s return to our sum
function. Accessing this
within the function will return window, our global object.
function sum(numbers) { let sum = 0; for (let x = 0; x < numbers.length; x++) { sum += numbers[x]; } console.log(this); // logs the 'Window' object return sum; }
If sum
was a property on an object, this
would reference that object.
var math = Object.create(null); math.sum = sum; math.sum(1, 2, 3); // console logs 'Object {}'
It is important to understand how this
behaves. The this
keyword can be tricky to use in a callback, especially when passing it into a third party library.
Function overloading doesn’t work quite like you’d expect it to
In JavaScript, if you tried to overload a function the same way you would in C#, you are overwriting the previously defined function. Take a look at the following snippet:
function add(x, y) { return x + y; } function add(x, y, z) { return x + y + z; }
The second function declaration will overwrite the previous one. The call add(1, 2)
will return NaN
instead of the value 3.
If you want to create a function with overrides, you can make use of the arguments array. To support function overloading, we can rewrite the snippet above as such:
function add() { if(arguments.length === 2) { return arguments[0] + arguments[1]; } else if (arguments.length === 3) { return arguments[0] + arguments[1] + arguments[2]; } }
(It’s not a best practice to use the arguments array.)
Recommended Reading
Disclosure: Some links are affiliate links.
Here’s a list of resources I found very useful in my journey with JavaScript:
- Mozilla Developer Network (MDN) JavaScript Reference
- Secrets of the JavaScript Ninja
- Effective JavaScript
- You Don’t Know JS (book series)