添加“toJSON"JavaScript对象实例的方法导致最大调用堆栈错误

Adding "toJSON" method a JavaScript object instance causes Maximum Callstack error

本文关键字:方法 错误 堆栈 调用 实例 toJSON quot 对象 JavaScript 添加      更新时间:2023-09-26

我想添加一个.toJson方法到一个实例化的JavaScript对象,这将允许我获得没有函数和原型的字符串化对象实例,在请求期间传输。

然而,似乎函数'toJSON'的实际名称作为方法名称影响JavaScript引擎(至少在V8)运行函数的能力-也就是说,如果您将相同的函数重命名为"JSON"而不是"toJSON",它可以工作,然而,作为"toJSON",它会导致最大Callstack错误。看到的例子:

function P1(name, age){
    this.name = name;
    this.age= age;
    this.toJSON = function(){
        return JSON.stringify(this);
    }
}
function P2(name, age){
    this.name = name;
    this.age= age;
    this.JSON = function(){
        return JSON.stringify(this);
    }
}
// This causes an error: Uncaught RangeError: Maximum call stack size exceeded(…)
var p1 = new P1('Memory Error', 10);
try {
  p1.toJSON();
} catch(e){
    console.log(e);
}
var p2 = new P2('No Error', 20);
p2.JSON();

这是JavaScript的预期行为吗?它是否与"toJSON"是本机方法有关(注意:我已经验证了在上面的实例化对象上,原型上没有toJSON方法会干扰实例上的重新定义)?我正在尝试决定是否应该将此作为bug报告给V8团队,或者这可以由更了解规范的人来解释。

谢谢

这不是.toJSON方法的用途。您使用.toJSON 覆盖默认的字符串化行为。.toJSONJSON.stringify内部调用,您不需要自己调用它。.toJSON可以返回字符串,对象,数组,任何你想在JSON.stringify的响应中被字符串化的东西。

你的.toJSON方法需要做一些其他的事情而不是调用JSON.stringify(this)。现在你得到一个无限循环,因为JSON.stringify(this)调用对象的.toJSON,等等。

试试这样写:

function P1(name, age){
    this.name = name;
    this.age= age;
    this.toJSON = function(){
        return {
            name: this.name,
            age: this.age
        };
    }
}
var p1 = new P1('Test', 10);
console.log(JSON.stringify(p1));