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

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

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

但是,函数的实际名称 'toJSON' 作为方法名称似乎会影响 JavaScript 引擎(至少在 V8 中)对 运行 函数的能力 -也就是说,如果您将完全相同的函数重命名为 "JSON" 而不是 "toJSON",它可以工作,但是,作为 "toJSON",它会导致最大调用堆栈错误。参见示例:

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 方法会干扰实例上的重新定义)?我正在尝试确定是否应该将此作为错误报告给 V8 团队,或者这可以由更了解该规范的人解释。

谢谢

这不是 .toJSON 方法的用途。您使用 .toJSON 覆盖 默认的字符串化行为。 .toJSONJSON.stringify内部调用,不需要自己调用。 .toJSON 可以 return 一个字符串、对象、数组,任何你想在来自 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));