5 Common/Uncommon JavaScript Mistakes

JavaScript is a very powerful language, as we all know “With great power comes great responsibility”

Original post

Working with JavaScript 364 days a year (Yes I do take Christmas day off), has resulted in many mistakes. We all make mistakes, below is a list of the 5 mistakes I can think of off the top of my head.

1: “this”

“this” is probably the most powerful and dangerous feature of JavaScript. The this context in JavaScript can allow developers to save time and effort to build powerful functions. At the same time it can cause a priority 1 defect in your application.


this.foo = 'foo';

document.querySelector('.my-div').onclick = function() {
  console.log(this.foo)
}
//Logs undefined

document.querySelector('.my-div').onclick = function() {
  console.log(this.foo)
}.bind(thid);
//Logs 'foo'

As you can see above the “this” context is not always what you expect.  The reason in the above example “this” is not foo is due to the scoping of the event handler. The event handler has its own “this” context. You can use bind to change the this context however with the use of ES6/ES2015 arrow functions you can control the scope of “this”.


this.foo = 'foo';

document.querySelector('.my-div').onclick = () => {
  console.log(this.foo)
}

2: Global Events

This is probably the least used and seen mistake however I have seen it and it cost me time debugging a error. IE and Chrome both expose a global event variable “Window.event”. This at first look this already looks bad as anything global is a code smell. Also the fact that only two browsers provide this should be a put off.


onClick: () => {
  console.log(Window.event);
}
//Bad 

onClick: (event) => {
  console.log(event);
}
//Good

3: Function Scope

Similar to “this” issues, function scope can cause problems at later stages. The most common and simple example of this is using timeouts inside a loop statement.


for (var i = 0; i < 5; i++) {
    setTimeout(function () {
        console.log(i);
    }, 1000);
}

However this can be overcome by using function binding:


for (var i = 0; i < 5; i++) {
    setTimeout(console.log.bind(this, i), 1000);
}

4: Object Equality


const chris1 = {
   name: 'Chris',
   location: 'Belfast'
}

const chris2 = {
   name: 'Chris',
   location: 'Belfast'
}

console.log(chris1 === chris2); //false
console.log(chris1 == chris2); //false

The reason for this is that internally JavaScript has two different approaches for testing equality. Primitives like strings and numbers are compared by their value, while objects like arrays, dates, and plain objects are compared by their reference. That comparison by reference basically checks to see if the objects given refer to the same location in memory. As we have created two different const variables they resided in two different blocks of memory. This can be tested using assignment by reference.


const chris1 = {
   name: 'Chris',
   location: 'Belfast'
}

const chris2 = {
   name: 'Chris',
   location: 'Belfast'
}

console.log(chris1 === chris2); //false
console.log(chris1 == chris2); //false

const chris3 = chris2;
console.log(chris3 == chris2); //true

You can use libraries like lodash to do object equality.

5: string.replace

By default string.replace does not work globally. When using string replace and the first case is matched it will stop. This will work for most cases when you know there is only one instance to replace. however when replacing items in a large string you will need to use the global flag.


const myString = "This string has many spaces";
console.log(myString.replace(/ /,""));
//"Thisstring has many spaces"
console.log(myString.replace(/ /g,""));
//"Thisstringhasmanyspaces"

 

If you liked this list you can see more common JavaScript in the great post by Ryan J. Peterson in the Toptal post 10 Most Common JavaScript Mistakes

 

chrislaughlin

 

Leave a Reply

Your email address will not be published. Required fields are marked *