js EVAL函数是否会改变元素的位置?

时间:2016-01-26 12:47:45

标签: javascript php

我有一个PHP和JS的应用程序。当我评估json编码的PHP数组时,数组排序会发生变化。例如,如果我在PHP中有一个这样的数组:

<?php 
$array = [148 => 'Plane', 149 => 'Car'];
?>

<script>
var array = eval(<?php echo json_encode($array)?>);
</script>

当我在控制台中打印数组时,元素的位置不同。你知道怎么会发生这种情况吗?

更新

感谢您的回答,但我想在JS结构中保持完全相同的顺序,所以我不想按特定字段对数组进行排序。也许从DB获得的订单就像:

[148 => object, 155 => object, 133 => object]

我想在JS中按照它的顺序创建一个这样的数组(位置来自DB,它必须是那个顺序)。有可能吗?

3 个答案:

答案 0 :(得分:8)

<?php echo json_encode($array)?>

由于数组是稀疏的,因此解析为

{"148":"Plane","149":"Car"}

这是JS中不保证的对象和对象属性顺序。

http://php.net/manual/en/function.json-encode.php

  

注意:   对数组进行编码时,如果键不是从0开始的连续数字序列,则所有键都编码为字符串,并为每个键值对明确指定。

您可以通过从对象创建数组来解决此问题,如下所示:

var obj = <?php echo json_encode($array)?>; // note, eval not needed
var arr = []; 
Object.keys(obj).forEach(function(key) { 
    arr[key] = obj[key]; 
});

关于更新:

您需要单独保存密钥的顺序。

var order = <?php echo json_encode(array_keys($array))?>;
var obj = <?php echo json_encode($array)?>;
order.forEach(function(key) {
    console.log(key, obj[key]); // or whatever you need
});

如果你使用ES6或ordered map,你甚至可以构造一个polyfill(PHP的数组实际上与JS中的数组不同)。

答案 1 :(得分:2)

早期的海报已经回答了这个问题。只是添加它:

许多人感到困惑,因为他们认为Javascript对象是PHP中的关联数组。然而事实并非如此。虽然我们可以(通过使用Javascript中的对象)来模拟靠近PHP关联数组的数据结构,但它们是完全不同的数据结构,并且与数组的工作方式完全不同。

在数组中,索引位置的完整性从数据结构和索引关系的角度来看很重要,这就是维护它们的顺序的原因。然而,同样的规则对于对象无关紧要,因为它们的&#34;伪命名索引&#34; (这实际上只是属性名称),不依赖于地方。它可以以任何顺序存在,只要该属性仍然具有分配给它的相同值。

希望这会有所帮助。

答案 2 :(得分:1)

您应该在这里区分两种类型的JSON数据结构。确保JSON解析器将您的数据放入所需的结构中。我建议它可能将它放入对象,而不是数组

直接从this answer抄袭:来自RFC 7159 - JavaScript对象表示法(JSON)数据交换格式(强调我的):

  

对象是零个或多个名称/值对的无序集合,其中名称是字符串,值是字符串,数字,布尔值,空值,对象或数组。 / p>      

数组是零个或多个值的有序序列。

     

术语“对象”和“数组”来自JavaScript的惯例。

并进一步引用this answer

  

维护数组([])中元素的顺序。 “对象”({})中元素的顺序(名称:值对)不是,并且它们通常是“混乱”,如果不是由JSON格式化程序/解析器本身,那么通过语言 - 特定对象(Dictionary,NSDictionary,Hashtable等),用作内部表示。