javascript - instanceof 在 JSON.stringify() 中的行为有何不同?

标签 javascript json decimal.js

我正在使用 decimal.js在 Node.js 中进行一些财务计算。我正在写一个自定义 JSON.stringify replacer function ,但是当我使用 instanceof 测试属性类型时,我得到的结果与我在替换函数之外进行相同测试时得到的结果不同。

这是一个可运行的例子:

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>

为什么会这样?

如果我将 Decimal 实例替换为我自己的自定义类的实例,则两个 instanceof 测试的行为与预期相同:

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);

最佳答案

想通了。 Decimal 实例包含一个 .toJSON() 方法。当 JSON.stringify 遇到定义了 toJSON 函数的对象时,它会调用它并将结果作为替换函数中的第二个参数而不是对象引用返回。因此,我上面示例中的 value 变量指向一个 string,而不是一个 Decimal 实例。

来自 MDN:

If an object being stringified has a property named toJSON whose value is a function, then the toJSON() method customizes JSON stringification behavior: instead of the object being serialized, the value returned by the toJSON() method when called will be serialized.

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);

关于javascript - instanceof 在 JSON.stringify() 中的行为有何不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49383222/

相关文章:

javascript - try {} without catch {} 可以在 JavaScript 中使用吗?

JavaScript 函数 eval() 抛出堆栈外配额异常

javascript - 在 NodeJS 中, 'Decimal' 也用作 'decimal'

javascript - 如何访问 Jade 模板提供的所有选项

javascript - 在 Android 6 中将 JavaScript 注入(inject) WebView

asp.net - 如何创建用于创建屏幕抓取的小书签?

javascript - node.js 嵌套 http req 对象未定义 - bodyParser.urlencoded({ 扩展 : true } not working

javascript - 检查数组元素是否已定义的简写

javascript - Decimal.js tan 的精度问题