【问题标题】:JSON.stringify doesn't work with normal Javascript arrayJSON.stringify 不适用于普通的 Javascript 数组
【发布时间】:2013-04-18 06:15:32
【问题描述】:

我一定是遗漏了一些东西,但是下面的代码 (Fiddle) 返回一个空字符串:

var test = new Array();
test['a'] = 'test';
test['b'] = 'test b';
var json = JSON.stringify(test);
alert(json);

对这个数组进行 JSON 处理的正确方法是什么?

【问题讨论】:

标签: javascript json


【解决方案1】:

JavaScript 数组旨在保存具有 数字 索引的数据。您可以向它们添加命名属性,因为an array is a type of object(当您想要存储有关包含正常、有序、数字索引数据的数组的元数据时,这可能很有用),但这不是它们的设计目的。

JSON 数组数据类型不能在数组上有命名键。

当您将 JavaScript 数组传递给 JSON.stringify 时,命名属性将被忽略。

如果您想要命名属性,请使用对象,而不是数组。

const test = {}; // Object
test.a = 'test';
test.b = []; // Array
test.b.push('item');
test.b.push('item2');
test.b.push('item3');
test.b.item4 = "A value"; // Ignored by JSON.stringify
const json = JSON.stringify(test);
console.log(json);

【讨论】:

  • 但是如果我使用一个Object,它没有像splice这样的数组原型。
  • @Michael — 也许你应该问一个新问题,在其中解释你的问题,由于某种原因需要你拼接一些具有命名属性的东西,你需要将这些属性字符串化为 JSON。
【解决方案2】:

很好的解释和上面的例子。我找到了这个(JSON.stringify() array bizarreness with Prototype.js)来完成答案。有些网站使用 JSONFilters 实现了自己的 toJSON,所以删除它。

if(window.Prototype) {
    delete Object.prototype.toJSON;
    delete Array.prototype.toJSON;
    delete Hash.prototype.toJSON;
    delete String.prototype.toJSON;
}

它工作正常并且测试的输出:

console.log(json);

结果:

"{"a":"test","b":["item","item2","item3"]}"

【讨论】:

  • 我在覆盖 Date 的网站上遇到了一些问题,所以当我使用 Date.toJSON 失败时,我添加了:Date.prototype.toJSON = Date.prototype.toISOString;
【解决方案3】:

我为此here发布了一个修复程序

您可以使用此函数将JSON.stringify 修改为编码arrays,只需将其发布在脚本开头附近(查看上面的链接了解更多详细信息):

// Upgrade for JSON.stringify, updated to allow arrays
(function(){
    // Convert array to object
    var convArrToObj = function(array){
        var thisEleObj = new Object();
        if(typeof array == "object"){
            for(var i in array){
                var thisEle = convArrToObj(array[i]);
                thisEleObj[i] = thisEle;
            }
        }else {
            thisEleObj = array;
        }
        return thisEleObj;
    };
    var oldJSONStringify = JSON.stringify;
    JSON.stringify = function(input){
        if(oldJSONStringify(input) == '[]')
            return oldJSONStringify(convArrToObj(input));
        else
            return oldJSONStringify(input);
    };
})();

【讨论】:

  • 这是一个不错的开始,但它做出了一些假设,例如,数组没有任何索引值。
【解决方案4】:

你也可以这样使用

var test = new Array();
test[0]={};
test[0]['a'] = 'test';
test[1]={};
test[1]['b'] = 'test b';
var json = JSON.stringify(test);
alert(json);

像这样你 JSON-ing 一个数组。

【讨论】:

    【解决方案5】:

    另一种方法是JSON.stringify() replacer function param。您可以将第二个参数传递给JSON.stringify(),它对空数组有特殊处理,如下所示。

    const arr = new Array();
    arr.answer = 42;
    
    // {"hello":"world","arr":{"answer":42}}
    JSON.stringify({ hello: 'world', arr }, function replacer(key, value) {
      if (Array.isArray(value) && value.length === 0) {
        return { ...value }; // Converts empty array with string properties into a POJO
      }
      return value;
    });
    

    【讨论】:

      【解决方案6】:

      Json 必须有键值对。你仍然可以将数组作为值部分。因此添加您选择的“关键”:

      var json = JSON.stringify({whatver: test});

      【讨论】:

      • 这是错误的。 JSON.stringify([15,12]) 会起作用。它会给"[15,12]"
      猜你喜欢
      • 2015-07-06
      • 1970-01-01
      • 2011-12-17
      • 2015-08-04
      • 1970-01-01
      • 1970-01-01
      • 2020-08-31
      • 1970-01-01
      • 2019-01-14
      相关资源
      最近更新 更多