How does the behavior of instanceof change when used within JSON.stringify()?

I am utilizing the decimal.js library for conducting financial calculations within Node. In my code, I have crafted a custom JSON.stringify replacer function. However, I have noticed a discrepancy in the results of property type tests conducted using instanceof within the replacer function compared to outside of it.

Below is an executable example:

const myObj = {
    myNum: new Decimal(0.3)
};

// output: 'Property "myNum" is a Decimal: true'
console.log('Property "myNum" is a Decimal:', myObj.myNum instanceof Decimal);

const replacer = (key, value) => {

    if (key === 'myNum') {
        // output: 'Property "myNum" is a Decimal: false'
        console.log('Property "myNum" is a Decimal:', value instanceof Decimal);
    }

    if (value instanceof Decimal) {
        return value.toNumber()
    } else {
        return value;
    }
}

JSON.stringify(myObj, replacer, 4);
<script src="https://cdnjs.cloudflare.com/ajax/libs/decimal.js/10.0.0/decimal.js"></script>

Can anyone explain this behavior?

Interestingly, when I substitute the Decimal instance with an instance of a custom class, both instanceof tests yield the same outcome, as anticipated:

function MyClass() {}

const myObj = {
    myClass: new MyClass()
};

// output: 'Property "myClass" is a MyClass: true'
console.log('Property "myClass" is a MyClass:', myObj.myClass instanceof MyClass);

const replacer = (key, value) => {

    if (key === 'myClass') {
        // output: 'Property "myClass" is a MyClass: true'
        console.log('Property "myClass" is a MyClass:', value instanceof MyClass);
    }

    return value;
}

JSON.stringify(myObj, replacer, 4);

Answer №1

I have managed to solve the issue. The Decimal instance comes with a .toJSON() method. When JSON.stringify comes across an object that has a toJSON function, it will invoke it and return the result as the second parameter in the replacer function instead of the object reference. This caused the value variable in my previous example to point to a string instead of a Decimal instance.

According to MDN:

If an object being stringified has a property named toJSON with a value that is a function, then the toJSON() method customizes JSON stringification behavior. Instead of serializing the object itself, the value that the toJSON() method returns upon invocation will be serialized.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#toJSON()_behavior

To demonstrate this concept, I can adjust my second example by adding a toJSON function:

function MyClass() {

    // defining a toJSON method for my custom class
    this.toJSON = () => {
        return 'Hello, world!';
    };
};

const myObj = {
    myClass: new MyClass()
};

// will display 'Property "myClass" is a MyClass: true'
console.log('Property "myClass" is a MyClass:', myObj.myClass instanceof MyClass);

const replacer = (key, value) => {

    if (key === 'myClass') {
        // will display 'Property "myClass" is a MyClass: true'
        console.log('Property "myClass" is a MyClass:', value instanceof MyClass);
    }

    return value;
}

JSON.stringify(myObj, replacer, 4);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Styling of Bootstrap HTML element not appearing as expected

Recently, I've been trying out a new approach by embedding Bootstrap components in an iframe. However, despite loading the necessary stylesheet and scripts, the elements seem to be missing their styles. Can anyone shed some light on why this might be ...

Angular-Translate fails to function within a tag's attribute

For my project, I utilize angular-translate. One of the key definitions looks like this: { "paging":{ "first":"First", "last":"Last", "next":"Next2", "pre":"Previous" } } I implement it in the following way: <uib-pagination first-tex ...

Get the latest bitcoin price using JSON in JAVA

Looking to retrieve the current or historical bitcoin price using JSON... Encountering an error in the code: Exception in thread "main" java.lang.NullPointerException at RwithJlab.Basic.main(Basic.java:19) ---------------------------------code------ ...

Find and extract elements from a nested array within an object inside another object within an array of objects

I am working with an array of objects that looks like this: [ { likes: [], _id: 5f254e21fd3e040640de38b2, content: 'try this', author: { posts: [Array], comments: [], images: [], followers: [Array], ...

Sending a parameter from a click event to a function

Struggling with a jQuery and AJAX issue all night. I am new to both and trying to implement something similar to this example. I have an edit button with the ID stored in a data-ID attribute. Here's an example of what my button looks like: <butto ...

Encountering difficulties in compiling Dynamic HTML with the $compile function

I'm attempting to incorporate dynamic HTML into my code with the following lines: var el = $compile('<a ng-controller=\"tableController\" ng-click=\"open\">...ReadMore</a>')($scope); But I'm encounterin ...

Using JQuery Ajax in Internet Explorer will only execute a single time

I've encountered an issue with my code where I have set cache to false, but in Internet Explorer it only runs once. Can someone please assist me with this problem? <script type="text/javascript" src="javascripts/jq1.7.js"></script> <sc ...

Design a TypeScript interface inspired by a set static array

I am working with an array of predefined strings and I need to create an interface based on them. To illustrate, here is an example of pseudo-interfaces: const options = ["option1", "option2", "option3"]; interface Selection { choice: keyof options; ...

Unraveling the mystery: Retrieving event.target.value in a React component

Having trouble accessing the event.target.value from a React child Component, but not an HTML tag? In this scenario: the Button tag (React Component) cannot access event.target.value, while the button tag (HTML tag) can. import React from "react"; impor ...

Attempting to grasp the intricacies of the express Router functionality

I'm a beginner with Node.js and I currently have three JS files: The Index.js file has the following code: var express = require('express'); var router = express.Router(); /* GET home page. */ router.get('/', function(req, r ...

Get rid of the arrow that is displayed when using the `time` input type in HTML5

Recently, I encountered an issue with the default HTML5 code snippet. My custom background looked perfect except for a pesky black arrow appearing on the right side. In this image, you can see the problematic black arrow that needs to be removed. I attemp ...

Retrieve specific components of objects using a GET request

When visitors land on my web app's homepage, a GET request is triggered to fetch a current list of Stadiums stored in the database through my API. However, the Stadium objects retrieved are packed with unnecessary data, particularly extensive arrays o ...

How come the 'color' property in the material-ui TextField functions properly, while the 'borderColor' property does not work as expected?

I am trying to show a TextField in orange color: <TextField id={field_meta.name} label={field_meta.title} defaultValue={field_meta.value? field_meta.value: ""} onChange={this.handleChange} margin="normal" inputProps={{style: {bo ...

JSON representing an array of strings in JavaScript

Encountering difficulties when trying to pass two arrays of strings as arguments in JSON format to call an ASMX Web Service method using jQuery's "POST". The Web Method looks like this: [ScriptMethod(ResponseFormat=ResponseFormat.Json)] publ ...

The RSS feed is stretching beyond the limits of the table's height

Seeking assistance to adjust the height of an RSS feed widget on my website. The widget is from RSS Dog and I do not have access to the style.css file as it is hosted externally. Despite trying to modify the JavaScript code provided by RSS Dog to set the h ...

Using jQuery to target nested HTML elements is a great way to efficiently manipulate

Within the code below, I have a complex HTML structure that is simplified: <div id="firstdiv" class="container"> <ul> <li id="4"> <a title="ID:4">Tree</a> <ul> <li id="005"> ...

Sorting multiple columns in Angular using the $filter and an array of predicate functions

For my Angular project, I need to order an array using the $filter('orderBy') function. Specifically, I want to specify three predicate callbacks and have the sort order be ASC, DESC, ASC. I am well aware that there are various methods to achiev ...

Provide the user with an .ics file for easy access

Recently, I developed an HTML5 application that enables users to download calendar entries in iCal format. These iCals are generated using PHP. Up until now, my method involved creating the iCal file with PHP and saving it to the web server's hard dis ...

Accessing a .mov File Online for Everyone

Looking for a way to host my lengthy .mov file on my own server but display it in a YouTube-style player that is compatible with all browsers. Any suggestions on how to achieve this easily? ...

Accessing a factory from within another in AngularJS Ionic

My Ionic app has been developed with two separate factories: one called Api, which handles API calls, and another called LDB (local database), responsible for interacting with a local Sqlite database using the CordovaSqlite plugin. While each factory work ...