添加"toJSON"方法JavaScript对象实例会导致Maximum Callstack错误

net*_*ica 2 javascript json ecmascript-5

我想为.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();
Run Code Online (Sandbox Code Playgroud)

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

谢谢

Roc*_*mat 8

这不是什么了 .toJSON方法的用途.您.toJSON用来覆盖默认的字符串化行为.在.toJSON被称为内部通过JSON.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));
Run Code Online (Sandbox Code Playgroud)