Converting Object to Primitives in JavaScript

Introduction

JavaScript is designed on an object-based paradigm. Everything in JavaScript is an object like Booleans, Numbers, Strings are objects if they are defined with the new keyword, and Dates, Maths, Regular Expressions, Arrays, and Functions are always objects. An object in JavaScript is a standalone entity that has its properties or variables.JavaScript provides built-in ways to convert between objects and primitive values; this article will cover the basics of these methods.

Understanding the Basics

Before moving forward with conversion, it's important to understand the difference between Primitive and Non-primitive values in JavaScript. In JavaScript, five primitive types are associated with various primitive values; Null is associated with value null, Number is associated with all numbers, like 0, 1, 2, ….. NaN and Infinity, Boolean is associated with values true and false and so on. All other values are non-primitive, including arrays, functions, and plain old objects. The below program illustrates the result of the typeof operator when applied to these values.

console.log(typeof null);
console.log(typeof {});
console.log(typeof []);

The output is:

object

object

object

Now, as you know about objects and primitives, it's time to find out what will happen when you add two objects, obj1 + obj2, or try to print it using alert(obj). 

If the answer is, according to you, another object, then you are wrong.

Surprising, isn't it! In JavaScript, we cannot implement a special object method to handle an addition or other operators, unlike other programming languages like Ruby and C++. So, in a nutshell, the addition of obj1 + obj2 cannot be another object.

JavaScript does not allow you to customize how operators work on objects, unlike other programming languages like Ruby, C++. In the case of such operations, objects are converted to primitives, and then the operations are carried out over primitives and result in a primitive value. We will cover how to convert the object to primitives and how we can customize these operations.

Conversion Rules

 If you are familiar with Type Conversions, you may know that there are some rules for conversion for numeric, string, and boolean conversions of primitives; similarly, there are rules for numericstring, and boolean conversions of objects; the rules are enlisted below:

  • Overall, objects are considered true in a boolean conversion. There are merely strings and numeric conversions.
  • The numeric conversions take place when subtracting objects or applying mathematical functions.
  • String conversion happens when we output an object like alert(obj) and in contexts like that.

There are three variants of type conversions of Object to Primitives:

  • Object to String conversion,
  • Object to Number conversion
  • Default case

ToPrimitive

According to MDN Docs, The Symbol.toPrimitive is a symbol that specifies a function valued property called to convert an object to a corresponding primitive value. Its syntax is:

Symbol()[Symbol.toPrimitive](hint);

Here Symbol is the object whose primitive value is to be found; this function accepts an optional parameter named "hint" and returns the primitive value of the given symbol object. The below example illustrates the ToPrimitive method by passing different hints

Example 1:

const object1 = {
  [Symbol.toPrimitive](hint) {
    if (hint === 'number') {
      return 100;
    }
    return null;
  }
};


console.log(+object1);

The output is 100

Let’s take another example wherein we will modify primitive values converted from an object. 

Example 2

// An object without Symbol.toPrimitive property.
var obj1 = {};
console.log(+obj1);     // Hint is number, Output will be NaN
console.log(`${obj1}`); // "Hint is string, Output will be [object Object]"
console.log(obj1 + ''); // Hint is default, Output will be "[object Object]"


// An object with Symbol.toPrimitive property.
var obj2 = {
  [Symbol.toPrimitive](hint) {
    if (hint == 'number') {
      return 100;
    }
    if (hint == 'string') {
      return 'hello';
    }
    return true;
  }
};
console.log(+obj2);     // 10, here hint is "number"
console.log(`${obj2}`); // "hello”, here  hint is "string"
console.log(obj2 + ''); // "true" , here hint is "default"

The above program illustrates how Symbol.toPrimitive property can modify the primitive values converted from an object by passing different hints,

toString/valueOf

If the method, Symbol.toPrimitive exists, it's used for all the hints, and no more methods are required; however, in the absence of toPrimitive method, JavaScript looks for the methods toString and valueOf:

  • Use the toString method if the hint is "string" The toString method returns a string, "[object Object]."
  • For all other hints, use the valueOf method. The valueOf method returns the object itself.

Here’s a simple example

var obj = {
   name: "Coding Ninjas"
};
console.log(obj); 

So if we try to use an object as a string as in the above example, we will see [object Object] by default. Therefore, anytime using an object as a string, you will have [object Object].

Now let's confirm whether the value returned by the valueOf method is an object or not.

var obj = {
   name: "Coding Ninjas"
};
console.log(obj.valueOf() == obj); 

The output is true, confirming that the value returned by the valueOf object is the object itself. Now that we know the basic usage of the toString and valueOf method let's look at some examples wherein we will do different types of conversions based on different hints.

Example 1:

let user = {
  name: "John",
  money: 10000,

 // for hint="string"
  toString() {
    return `{name: "${this.name}"}`;
  },

  // for hint="number" or "default"
  valueOf() {
    return this.money;
  }
};
console.log(user); // Hint is String
console.log(+user); // Hint is number

The output is:

{ name: 'John',

  money: 10000,

  toString: [Function: toString],

  valueOf: [Function: valueOf] }

10000

The behavior is the same as with the previous example of Symbol.toPrimitive.

Example 2:

Let's look at another example wherein we will only use the toString() method to handle all the primitive conversions. We will pass one hint as String and another one for hint = number.

let user = {
  name: "John",
 toString() {
    return this. name;
  }
};


console.log(user); // hint is string
console.log(+user); // hint is number

The output is:

{ name: 'John', toString: [Function: toString] }

NaN

Note that in the above example, NaN is being displayed when the passed hint is a number. This means that in the absence of Symbol.toPrimitive and valueOftoString will handle all primitive conversions.

Examples of Object to Primitive Conversion

Many operators and functions perform type conversions; for example, multiplication converts operands to numbers. So while performing operations on Objects, the object is first converted to a primitive, and then the desired operations are performed. Let's take a look at an example to understand this:

let obj = {
 toString() {
    return "100";
  }
};
console.log(obj * 2); 

The output is 2. Behind the scenes, 

  • The multiplication obj * 2 first converts the object to primitive (a string "100").
  • Then "2" * 2 becomes 2 * 2 (the string is converted to a number).

Similarly, the plus operator will concatenate strings, as illustrated in the following example,

let obj = {
   toString() {
    return "100";
  }
};

console.log(obj + 2); 

The output is 1002

You may refer to the following table to understand which method is called when

obj[Symbol.toPrimitive](hint)This will be called if this exists in the program
obj.toString()If the hint is a string.
obj.valueOf()If the hint is number or default.

In general, it's enough to implement only obj.toString() as a "catch-all" method for string conversions that should return a "human-readable" representation of an object for logging or debugging purposes.

Frequently Asked Questions

Q1) How do you change an Object to Primitive?
Ans 1) To do the conversion from JavaScript object to primitives, JavaScript tries to find and call three object methods:

  1. Call obj[Symbol.toPrimitive](hint) – the method with the symbolic key Symbol.toPrimitive (system symbol), if such method exists,
  2. Otherwise if hint is "string"
    • try obj.toString() and obj.valueOf(), whatever exists.
  3. Otherwise if hint is "number" or "default"
    • try obj.valueOf() and obj.toString(), whatever exists.

Q2) Is an object a primitive type in JavaScript?
Ans 2) In JavaScript, a primitive (primitive value, primitive data type) is not an object and has no methods. There are seven primitive data types: string, number, bigint, boolean, undefined, symbol, and null. All primitives are immutable, i.e., they cannot be altered. 

Key Takeaways

This blog discussed Object to Primitive conversion in JavaScript.

Now that you know the concept of variables and data types in Javascript, go ahead and try out some interview questions based on them on our CodeStudio Platform! Don't stop here. Check out our Basics of JavaScript - guided path to learn JavaScript from scratch. If you are preparing for JavaScript Interviews, check out the blog Javascript Interview Questions.

 We hope you found this blog useful. Feel free to let us know your thoughts in the comments section.

Was this article helpful ?
0 upvotes

Comments

No comments yet

Be the first to share what you think