Why I like JavaScript

Every programming language has its oddities and challenges. When it comes to JavaScript, it has Every programming language has its oddities and challenges. When it comes to JavaScript, it has probably more of those oddities. It’s not the just language itself but also browser support and the long tail of old decisions. Different vendors implemented slightly different JavaScript engines for years which basically meant same code, different universe. It resulted in a ton of challenges for anyone shipping real products. I dealt with these challenges myself the hard way myself. Thanks to JQuery, we had a fresh air and for a while it felt like sanity. Anyway, this isn’t the end of the story because JavaScript kept evolving instead of collapsing under its own quirks. Over the years, JavaScript improved a lot, really and ES6 was the moment it stopped feeling like a necessary evil. In this post, I’ll go over JavaScript weirdnesses first the ones you actually bump into and then try to explain why I like JavaScript despite all of that.

The Weird Parts

JavaScript has weird parts. Some of them are harmless trivia. Not the [] == ![] kind that people share for fun. I mean the kind that turns into a bug, then a workaround, then technical debt, then a comment you do not want to explain six months later.

Most of this weirdness is not random. It is historical. JavaScript grew inside browsers. Browsers competed. Engines behaved differently. People shipped code anyway. And once something is on the web, it is basically forever.

So when I say weird parts, I am not trying to be clever. Or provocative. I am trying to separate trivia from the stuff that actually matters. In the next section, I will go over the oddities that have practical consequences, coercion rules, equality, this, undefined, NaN. I will not over-explain them. I will directly go to code as it’s better to demonstrate than talk.

// ===============================
// JavaScript Weird Parts – 2018-friendly (ES5-style)
// One file. No arrow functions. No optional chaining.
// ===============================


// Equality & coercion
0 == false;               // true
0 === false;              // false

"" == 0;                  // true
"" === 0;                 // false

null == undefined;        // true
null === undefined;       // false

[] == false;              // true
[] === false;             // false

[0] == 0;                 // true
[0] === 0;                // false

"0" == false;             // true
"0" === false;            // false


// NaN
NaN === NaN;              // false
isNaN("foo");             // true  (coercion)
Number.isNaN("foo");      // false (no coercion)
Number.isNaN(NaN);        // true


// typeof (historical baggage)
typeof null;              // "object"
typeof NaN;               // "number"
typeof [];                // "object"


// Arrays & objects doing "math"
[] + [];                  // ""
[] + {};                  // "[object Object]"
({} + []);                // "[object Object]"  // force object literal as expression

[1,2] + [3,4];            // "1,23,4"
+[];                      // 0
+[1];                     // 1
+[1,2];                   // NaN


// this depends on how, not where
var obj = {
  value: 42,
  get: function () {
    return this.value;
  }
};

var fn = obj.get;
fn();                     // undefined (or throws under strict mode if you go deeper)
obj.get();                // 42


// Strict mode flips some defaults
(function () {
  "use strict";

  function plain() { return this; }
  plain();                // undefined

  // Uncomment to see the classic implicit-global fail in strict mode:
  // function leak() { x = 10; }
  // leak();               // ReferenceError
})();


// Hoisting (var)
console.log(a);           // undefined
var a = 10;


// Function declaration hoisting vs function expression
hoisted();                // "ok"
function hoisted() { console.log("ok"); }

try {
  notHoisted();           // TypeError: notHoisted is not a function
} catch (e) {}

var notHoisted = function () { console.log("nope"); };


// delete on arrays leaves holes
var arr = [1, 2, 3];
delete arr[1];
arr;                      // [1, empty, 3]
arr.length;               // 3


// for..in on arrays is not your friend
var arr2 = [10, 20, 30];
arr2.extra = 99;

for (var k in arr2) {
  k;                      // "0", "1", "2", "extra"
}


// Floating point math
0.1 + 0.2 === 0.3;        // false
0.1 + 0.2;                // 0.30000000000000004


// parseInt surprises
parseInt("08");           // 8
parseInt("08", 10);       // 8 (be explicit)
parseInt("0x10");         // 16
parseInt("10", 2);        // 2


// Automatic semicolon insertion (ASI)
function returnsObjectWrong() {
  return
  {
    ok: true
  };
}
returnsObjectWrong();     // undefined

function returnsObjectRight() {
  return {
    ok: true
  };
}
returnsObjectRight();     // { ok: true }

We can probably find more of these peculiarities but I’ll keep it short. Let’s focus on the new syntax.

The Good Parts

ES6 is a significant update to the language. It introduced a powerful syntax. I have been using JavaScript fES6 is a significant update to the language. It is the point where JavaScript starts feeling like a modern language instead of a historical accident. It introduced a proper pow…y time I get to use them. So, I’ll go over my favorite features and show them with code, because these are best understood by seeing them in action.

The Default Parameters

I’ve first used default parameters in Python and it was charming. It simplifies the code by removing extra logic to cover null cases.

function increment(i, inc = 1) {
  return i + inc;
}

The Arrow Functions

I guess it’s not just me. Everbody loves arrows, it simplifies logic for filtering and mapping a lot. Note that, we have some brand new functionality like some and every. They are wonderful. You simply write less.

[1, 2, 3].map(i => i + 1).reduce((s, i) => s + i)
[1, 2, 3].filter(i => i % 2 == 0).sort()
[1, 2, 3].some(i => i % 2 == 0)
[1, 2, 3].every(i => i % 2 == 0)

The Template Strings

The template string is just better way of constructing strings. It removes the challenge to format strings. It can also evaluate the logic inside although it might not be a very good idea to do so.

let name='Gulnihal', postId=3, commentId=5
console.log(`Hello ${name}`)
let url = `https://yusufaytas.com/posts/${postId}/comments/${commentId}`
console.log(url)

Destructuring assignment

This is truly magical. You can destruct objects and arrays. You can just get the property you are looking for easily.

const [a, ...b] = [1, 2, 3]; // a becomes 1 and b becomes [2, 3]
const {id, person} = { id: 3, person: {name: 'Gulnihal'}} // id becomes 3 and person becomes {name: 'Gulnihal'}
const newArray = [1, ...[2, 3]]; //newArray becomes [1,2,3]
//You can also destruct in a for loop
const people = [{ id: 3, person: {name: 'Gulnihal'}}]
for (var {id: id, person: {name: name}} of people) {
  console.log(`The person with id=${id} is ${name}.`);
}

ES6 is a significant update to the language. It is the point where JavaScript starts feeling like a modern language instead of a historical accident. It introduced a proper module system, sane scoping with let and const, defaults that actually work, destructuring that removes boilerplate, and promises that finally made async code readable. Not syntactic sugar for the sake of it, but tools that reduce entire classes of bugs. So, I’ll go over my favorite features the ones I actually reach for in real projects, and show them with code, because these are best understood by seeing them in action.

All in All

I’ve gone through my favorites with the new JavaScript features. There are other great features like Promises, Classes and additional object methods. However, the above features changed my daily coding significantly because I’m writing less code in a much more expressive way. In consequence, JavaScript has been the bad guy for a while but it significantly improved. One can accept weird parts and avoid them.

Stay updated

Receive insights on tech, leadership, and growth.

Subscribe if you want to read posts like this

No spam. One email a month.

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.