为什么JavaScript对象没有toJSON()方法?

时间:2022-10-01 22:25:48

As described at http://www.json.org/js.html, JavaScript objects can dictate how they are serialized by JSON.stringify() by implementing a toJSON() method. For an arbitrary object, this method is not defined, while numbers and strings seem to implement the method. I'm curious--why do objects not have an implementation?

如http://www.json.org/js.html所述,JavaScript对象可以通过实现toJSON()方法来规定JSON.stringify()如何序列化它们。对于任意对象,此方法未定义,而数字和字符串似乎实现该方法。我很好奇 - 为什么对象没有实现?

EDIT: I originally mentioned that arrays have this method--they do not. I apologize for the confusion.

编辑:我最初提到阵列有这种方法 - 他们没有。我为这种困惑道歉。

6 个解决方案

#1


5  

Those methods you mention were added by some JavaScript engines (AFAIK the latest versions of V8 and Tracemonkey implement them):

你提到的那些方法是由一些JavaScript引擎添加的(AFAIK最新版本的V8和Tracemonkey实现它们):

String.prototype.toJSON
Boolean.prototype.toJSON
Number.prototype.toJSON
Date.prototype.toJSON

Although the only standarized by the ECMAScript 5 Specification is the Date.prototype.toJSON.

虽然ECMAScript 5规范的唯一标准是Date.prototype.toJSON。

Personally I think those methods aren't much useful at all, the results from String, Boolean, and Number are completely equivalent to calling the valueOf method, and the result from Date is equivalent to calling toISOString.

我个人认为这些方法根本没用,String,Boolean和Number的结果完全等同于调用valueOf方法,而Date的结果相当于调用toISOString。

So the question was: Why native objects not have a toJSON() method?

所以问题是:为什么本机对象没有toJSON()方法?

Well, with the JSON Object available (Section 15.12), adding another method to the Object.prototype is not worth, and really I think it would be a bad idea adding it...

好吧,有了JSON对象可用(第15.12节),向Object.prototype添加另一个方法是不值得的,而且我认为添加它是个坏主意...

#2


5  

The Real Reason

While @CMS is correct, the Browser makes have added these, the point was missed entirely. The reason is that the JSON Specification calls for an optional toJSON method for any object which, in turn, gets called to serialize a non-normative structure into a normative one.

虽然@CMS是正确的,但是浏览器已经添加了这些,完全错过了这一点。原因是JSON规范为任何对象调用可选的toJSON方法,而后者又被调用以将非规范性结构序列化为规范性结构。

var O = function O() {
    this.val = 'value';
    this.toJSON = function () { return ['VALUE!']; };
};

var o = new O();
var s = JSON.stringify(o);

console.log(s);  // >> ["VALUE!"]

An example would be a Set Data-Structure whose structure is actually an object which has a values method. This would allow one to write this.toJSON = values; to provide the JSON.stringify method the right serialization-strategy.

一个例子是Set Data-Structure,其结构实际上是一个具有values方法的对象。这将允许人们写这个.toJSON =值;为JSON.stringify方法提供正确的序列化策略。

So, in a nutshell, its to provide JSON.stringify the correct strategy for outputting alternative structures.

因此,简而言之,它为JSON.stringify提供了输出替代结构的正确策略。

Hope this helps.

希望这可以帮助。

#3


3  

I don't think its the case that Numbers, etc have default toJSON implementations. Maybe you are using Prototype or some other framework?

我不认为Numbers等具有默认的JSON实现。也许你正在使用Prototype或其他一些框架?

http://www.w3schools.com/jsref/jsref_obj_number.asp

http://www.w3schools.com/jsref/jsref_obj_number.asp

http://www.w3schools.com/jsref/jsref_obj_array.asp

http://www.w3schools.com/jsref/jsref_obj_array.asp

From http://www.prototypejs.org/learn/json :

来自http://www.prototypejs.org/learn/json:

Encoding

编码

Prototype’s JSON encoding slightly differs from Crockford’s implementation as it does not extend Object.prototype. The following methods are available: Number#toJSON, String#toJSON, Array#toJSON, Hash#toJSON, Date#toJSON and Object.toJSON.

Prototype的JSON编码与Crockford的实现略有不同,因为它没有扩展Object.prototype。可以使用以下方法:Number#toJSON,String#toJSON,Array#toJSON,Hash#toJSON,Date#toJSON和Object.toJSON。

#4


0  

It's a standard to not implement functions on arbitrary objects.

它是不在任意对象上实现函数的标准。

try console.log({}) and you'll see nothing.

尝试console.log({}),你什么也看不见。

#5


0  

What properties would it save? A plain old object doesn't have any.

它会节省什么属性?一个普通的旧物体没有任何物体。

#6


-3  

I doubt this is a reason - arrays don't seem to have them either. Here's how I'd implement it:

我怀疑这是一个原因 - 数组似乎也没有它们。这是我如何实现它:

Array.prototype.toJSON = Object.prototype.toJSON = function() {
  return JSON.stringify(this);
}

#1


5  

Those methods you mention were added by some JavaScript engines (AFAIK the latest versions of V8 and Tracemonkey implement them):

你提到的那些方法是由一些JavaScript引擎添加的(AFAIK最新版本的V8和Tracemonkey实现它们):

String.prototype.toJSON
Boolean.prototype.toJSON
Number.prototype.toJSON
Date.prototype.toJSON

Although the only standarized by the ECMAScript 5 Specification is the Date.prototype.toJSON.

虽然ECMAScript 5规范的唯一标准是Date.prototype.toJSON。

Personally I think those methods aren't much useful at all, the results from String, Boolean, and Number are completely equivalent to calling the valueOf method, and the result from Date is equivalent to calling toISOString.

我个人认为这些方法根本没用,String,Boolean和Number的结果完全等同于调用valueOf方法,而Date的结果相当于调用toISOString。

So the question was: Why native objects not have a toJSON() method?

所以问题是:为什么本机对象没有toJSON()方法?

Well, with the JSON Object available (Section 15.12), adding another method to the Object.prototype is not worth, and really I think it would be a bad idea adding it...

好吧,有了JSON对象可用(第15.12节),向Object.prototype添加另一个方法是不值得的,而且我认为添加它是个坏主意...

#2


5  

The Real Reason

While @CMS is correct, the Browser makes have added these, the point was missed entirely. The reason is that the JSON Specification calls for an optional toJSON method for any object which, in turn, gets called to serialize a non-normative structure into a normative one.

虽然@CMS是正确的,但是浏览器已经添加了这些,完全错过了这一点。原因是JSON规范为任何对象调用可选的toJSON方法,而后者又被调用以将非规范性结构序列化为规范性结构。

var O = function O() {
    this.val = 'value';
    this.toJSON = function () { return ['VALUE!']; };
};

var o = new O();
var s = JSON.stringify(o);

console.log(s);  // >> ["VALUE!"]

An example would be a Set Data-Structure whose structure is actually an object which has a values method. This would allow one to write this.toJSON = values; to provide the JSON.stringify method the right serialization-strategy.

一个例子是Set Data-Structure,其结构实际上是一个具有values方法的对象。这将允许人们写这个.toJSON =值;为JSON.stringify方法提供正确的序列化策略。

So, in a nutshell, its to provide JSON.stringify the correct strategy for outputting alternative structures.

因此,简而言之,它为JSON.stringify提供了输出替代结构的正确策略。

Hope this helps.

希望这可以帮助。

#3


3  

I don't think its the case that Numbers, etc have default toJSON implementations. Maybe you are using Prototype or some other framework?

我不认为Numbers等具有默认的JSON实现。也许你正在使用Prototype或其他一些框架?

http://www.w3schools.com/jsref/jsref_obj_number.asp

http://www.w3schools.com/jsref/jsref_obj_number.asp

http://www.w3schools.com/jsref/jsref_obj_array.asp

http://www.w3schools.com/jsref/jsref_obj_array.asp

From http://www.prototypejs.org/learn/json :

来自http://www.prototypejs.org/learn/json:

Encoding

编码

Prototype’s JSON encoding slightly differs from Crockford’s implementation as it does not extend Object.prototype. The following methods are available: Number#toJSON, String#toJSON, Array#toJSON, Hash#toJSON, Date#toJSON and Object.toJSON.

Prototype的JSON编码与Crockford的实现略有不同,因为它没有扩展Object.prototype。可以使用以下方法:Number#toJSON,String#toJSON,Array#toJSON,Hash#toJSON,Date#toJSON和Object.toJSON。

#4


0  

It's a standard to not implement functions on arbitrary objects.

它是不在任意对象上实现函数的标准。

try console.log({}) and you'll see nothing.

尝试console.log({}),你什么也看不见。

#5


0  

What properties would it save? A plain old object doesn't have any.

它会节省什么属性?一个普通的旧物体没有任何物体。

#6


-3  

I doubt this is a reason - arrays don't seem to have them either. Here's how I'd implement it:

我怀疑这是一个原因 - 数组似乎也没有它们。这是我如何实现它:

Array.prototype.toJSON = Object.prototype.toJSON = function() {
  return JSON.stringify(this);
}