Categories
JavaScript Best Practices

Better JavaScript — Primitives

Spread the love

Like any kind of apps, JavaScript apps also have to be written well.

Otherwise, we run into all kinds of issues later on.

In this article, we’ll look at ways to improve our JavaScript code.

Converting Objects to Primitives

Objects can be converted to numbers with the valueOf method.

For instance, we can write:

const obj = {
  valueOf() {
    return 3;
  }
};

console.log(2 + obj);

then we see 5 logged.

We can so convert an object to a string with:

const obj = {
  toString() {
    return 'bar';
  }
};

console.log('foo' + obj);

Then we get:

'foobar'

logged.

If an object has both the valueOf and toString methods, then it’s not obvious which one will be run.

So if we have:

const obj = {
  toString() {
    return "[object obj]";
  },
  valueOf() {
    return 'bar';
  }
};

console.log('foo' + obj);

Then we see 'foobar' logged.

So we know that valueOf will be run if both valueOf and toString are both present.

valueOf is designed to be used for objects that represents numeric values like Number objects.

For these objects, toString and valueOf are consistent.

They both return the string representation of a number.

Coercion to strings are far more common than coercion to numbers.

It’s best to avoid valueOf unless the object is an abstraction of numbers.

Another kind of coercion is known as truthiness.

The || and && work with boolean values, but they can accept anything.

If a value is truthy, then they’re coerced to true .

Otherwise, they’re falsy and they’re coerced to false .

false, 0, -0, “”, NaN, null, and undefined are falsy.

Other values are all truthy.

The || operator lets us return a default value if the first operand is falsy.

For instance, instead of writing:

function point(x, y) {
  if (!x) {
    x = 10;
  }
  if (!y) {
    y = 20;
  }
  return {
    x,
    y
  };
}

or:

function point(x, y) {
  if (typeof x === "undefined") {
    x = 10;
  }
  if (typeof y === "undefined") {
    y = 20;
  }

  return {
    x,
    y
  };
}

We can write:

function point(x, y) {
  x = x || 10;
  y = y || 20;
  return {
    x,
    y
  };
}

The || operator takes all falsy values and returns the second operand if the first one is falsy.

Primitives are Better than Object Wrappers

Primitives are better than object wrappers.

JavaScript has various kinds of primitive values.

They include boolean, numbers, strings, null and undefined .

null is reported as 'object' with the typeof operator but its defined as a separate type in the ES standard.

The JavaScript standard library also provides constructors for these objects.

So, we can write:

const s = new String("hello");

or:

const str = "hello";

We can extract a character with the square brackets.

For instance, we can write:

s[4]

and we get 'o' .

But if have:

typeof s

it returns 'object' .

But if we have:

typeof str

then we get 'string' .

And if we have:

const s1 = new String("foo");
const s2 = new String("foo");

and if we write:

s1 === s2

it returns false since the references are different.

It can only be equal to itself.

As we can see, this is a problem that we have with string wrapper objects and other primitive wrappers.

Conclusion

We shouldn’t use primitive wrapper objects.

They aren’t useful in our code.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

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