What does instanceof do differently in JSON.stringify ()?

I use decimal.js for some financial calculations in Node. I am writing a custom JSON.stringify substitute function , but when I test property types with instanceof, I get a different result than when I perform the same test outside the replacement function.

Here is an example:

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

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

const replacer = (key, value) => {

    if (key === 'myNum') {
        // logs '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>
Run codeHide result

Why is this happening?

If you replace the instance with an Decimalinstance of my own class, then both tests instanceofwill behave the same, as expected:

function MyClass() {}

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

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

const replacer = (key, value) => {

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

    return value;
}

JSON.stringify(myObj, replacer, 4);
Run codeHide result
+4
source share
1 answer

. Decimal .toJSON(). JSON.stringify , toJSON, replacer . value string, Decimal.

MDN:

toJSON, , toJSON() JSON: , toJSON() .

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

, , toJSON:

function MyClass() {

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

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

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

const replacer = (key, value) => {

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

    return value;
}

JSON.stringify(myObj, replacer, 4);
Hide result
0

Source: https://habr.com/ru/post/1695103/


All Articles