如何最好地将字符串转换为JavaScript中的对象数组?

30

我想在JavaScript中将下面的字符串转换为数组。

{a:12, b:c, foo:bar}

我该如何将这个字符串转换为对象数组?有什么好的想法吗?


2
这个数组会是什么样子? - Nick Craver
1
那看起来很像JSON。它本身就很像一个关联数组,可以像访问关联数组一样访问它。你知道这个吗?看这里 - BalusC
这不是一个数组,而是一个单独的字符串。我只是从标签属性中获取了这个字符串。我想将这个字符串转换成一个数组。 - Zeck
2
他们的意思是,在JavaScript中,对象的功能与数组非常相似。如果您将键/值用单引号括起来并在其上使用toJSON,则您提供的示例实际上将创建一个JavaScript对象。 - prodigitalson
我假设你的意思是 {a: 12, b: "c", foo: "bar"} ... 除非 cbar 实际上是当前作用域中的变量,而不是字符串。 - Anthony Mills
7个回答

84
我认为最好的方法是使用JavaScript大师Douglas Crockford在此处建议的JSON原生解析器,因为它不仅比eval()更快,而且更安全。
原生JSON解析器已经在以下浏览器中可用:
  • Firefox 3.5+
  • IE 8+
  • Opera 10.5+
  • Safari Safari 4.0.3+
  • Chrome(不知道哪个版本)
Crockford还制作了一个名为json2.js的JavaScript安全回退,它是对eval()方法的改进,添加了一些安全位并使用了原生JSON解析器API。您只需要包含该文件,删除其第一行,并使用原生JSON解析器,如果不存在,则json2将完成工作。
下面是一个示例:
var myJSONString = '{ "a": 1, "b": 2 }',
    myObject = JSON.parse(myJSONString);

一旦解析完成,你将得到一个带有属性ab的对象。正如你所知,在JavaScript中,你可以将对象视为哈希表或关联数组,因此你可以像这样访问值:

myObject['a'];

如果你只需要一个简单的数组而不是关联数组,可以这样做:

var myArray = [];
for(var i in myObject) {
    myArray.push(myObject[i]);
}

最后,虽然在普通的JavaScript中不是必需的,但JSON规范要求成员的键用双引号括起来。因此,如果没有这个要求,原生解析器将无法工作。如果我是你,我会添加它,但如果不可能,可以使用var myObject = eval("(" + myString + ")");方法。

var myObject = eval("(" + myString + ")"); 这段代码的意思是什么?非常感谢。 - MEM
1
eval()函数将字符串解析为JavaScript源代码,由于所有有效的JSON也是有效的JavaScript(并且它来自JavaScript对象表示法),因此您可以使用eval()将其转换为JavaScript表示形式。出于安全原因,在字符串开头和结尾添加括号是一种常见做法,尽管使用eval()仍然不太安全。因此,var myObject = eval("(" + myString + ")"); 只是解析myString JSON并在myObject变量中获取其值(可能是对象或数组)。 - alcuadrado
请注意,json2仍然使用eval,但执行一些检查以减轻潜在的漏洞。 - Russ Cam

10

由于您的字符串是格式不正确的JSON,因此JSON解析器无法正确解析它,即使使用eval()也会抛出错误。它也不是数组,而是哈希表或简单的对象文字(格式不正确)。如果对象字面量仅包含数字和字符串值(没有子对象/数组),则可以使用以下代码。

function malformedJSON2Array (tar) {
    var arr = [];
    tar = tar.replace(/^\{|\}$/g,'').split(',');
    for(var i=0,cur,pair;cur=tar[i];i++){
        arr[i] = {};
        pair = cur.split(':');
        arr[i][pair[0]] = /^\d*$/.test(pair[1]) ? +pair[1] : pair[1];
    }
    return arr;
}

malformedJSON2Array("{a:12, b:c, foo:bar}");
// result -> [{a:12},{b:'c'},{foo:'bar'}]

这段代码将把你的字符串转换成一个对象数组(复数)。

然而如果你真的想要一个HashMap(关联数组)而不是一个数组,请使用以下代码:

function malformedJSON2Object(tar) {
    var obj = {};
    tar = tar.replace(/^\{|\}$/g,'').split(',');
    for(var i=0,cur,pair;cur=tar[i];i++){
        pair = cur.split(':');
        obj[pair[0]] = /^\d*$/.test(pair[1]) ? +pair[1] : pair[1];
    }
    return obj;
}

malformedJSON2Object("{a:12, b:c, foo:bar}");
// result -> {a:12,b:'c',foo:'bar'}

当您开始嵌套对象和数组时,上述代码将变得更加复杂。基本上,您必须重新编写JSON.jsJSON2.js以支持格式错误的JSON。

此外,请考虑以下选项,虽然仍然不太好,但比将JSON放在HTML标记属性中要好一些。

<div id="DATA001">bla</div>
<!-- namespacing your data is even better! -->
<script>var DATA001 = {a:12,b:"c",foo:"bar"};</script>

我假设您在字符串中省略引号,因为您将其放入HTML标记的属性中,并且不想转义引号。


8
最简单但不安全的方法是:
eval('(' + myJSONtext + ')')

但是,由于这将解释任何 JavaScript 代码,因此存在安全漏洞。为了防止这种情况发生,请使用 JSON 解析器。如果您正在使用框架(jquery、mootools 等),则有一个特定于框架的调用。它们大多基于 Douglas Crawford 的解析器,可在 http://www.json.org/js.html 上获得。


据我所知,只有在 eval 处理用户输入的内容时才会存在漏洞。我假设用户不会涉及到这个问题。 - johny why

2

使用JSON.parse即可达到效果,解析完成后可以将它们推入数组中。

var object = JSON.parse(param);
var array = [];
for(var i in object) {
   array.push(object[i]);
}

2
您可以使用 "for in"。
var myObject = {a:'12', b:'c', foo:'bar'};
var myArray = [];

for(key in myObject) {
    var value = myObject[key];
    myArray[key] = value;
}

myArray['a']; // returns 12

注意:考虑到myObject只有一级键值对。

如果你真的想使用字符串,可以按照@Rob的提示,将第一行改为 var myObject = eval('(' + "{a:'12', b:'c', foo:'bar'}" + ')');。 - Topera

1

如果您正在使用jQuery,那么有$.parseJSON()函数。它会在字符串格式不正确时抛出异常,"另外,如果您传入任何参数为空字符串、null或未定义的情况,parseJSON 将返回 'null'。当浏览器提供了本地的JSON.parse实现时,jQuery将使用它来解析字符串"


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接