Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/416.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
“Javascript持久排序对象”;“类”;_Javascript_Json - Fatal编程技术网

“Javascript持久排序对象”;“类”;

“Javascript持久排序对象”;“类”;,javascript,json,Javascript,Json,根据它的规范,JSON元素(和javascript对象)是无序的,因此,即使在几乎所有情况下,当您迭代javascript对象时,您也会按照定义的相同顺序获取元素;您肯定不能信任该顺序,因为允许引擎更改它 这是极为罕见的。我曾经观察过一次,但是我现在没有找到代码,我也不记得JS引擎的确切版本(但它是node)。如果我能找到它,我会把它添加到这篇文章中 话虽如此,关键是依赖于这种行为的代码可能(也应该)被认为是有缺陷的,因为即使它在大多数引擎中都能按预期工作,它也可能因为内部引擎优化而失败 例如:

根据它的规范,JSON元素(和javascript对象)是无序的,因此,即使在几乎所有情况下,当您迭代javascript对象时,您也会按照定义的相同顺序获取元素;您肯定不能信任该顺序,因为允许引擎更改它

这是极为罕见的。我曾经观察过一次,但是我现在没有找到代码,我也不记得JS引擎的确切版本(但它是node)。如果我能找到它,我会把它添加到这篇文章中

话虽如此,关键是依赖于这种行为的代码可能(也应该)被认为是有缺陷的,因为即使它在大多数引擎中都能按预期工作,它也可能因为内部引擎优化而失败

例如:

"use strict";
var x = {
    b: 23,
    a: 7
};

function someSorting(input) {
    var output = {};
    Object.keys(input).sort().map(
        function(k){
            output[k] = input[k];
        }
    );
    return output;
};

x = someSorting(x);
// Some smart engine could notice that input and output objects have the
// exact same properties and guess that, attending the unordered nature of
// javascript Object, there is no need to actually execute someSorting();

console.log(x);
// Usually will display: { a: 7, b: 23 }
// But perfectly we could got: { b: 23, a: 7 }
我知道关于这个(非)问题和“工作区”的文献太多(甚至是堆栈溢出问题),无法通过在单独的数组中排序键来实现预期的行为

但这样做的代码与简单地信任密钥顺序相比太混乱了

我非常确信,通过实现一个所谓的“sObject”替代方案,将本机对象作为其原型,但重载其本机迭代器和setter,可以以更优雅的方式实现这一点,以便:

  • 当添加任何新属性时,它的键将附加到一个数组索引中,该数组索引位于引擎盖下
  • 当对sObject实例进行迭代时,我们的定制迭代器使用该索引以正确的顺序检索元素
总之:实际的对象规范是正确的,因为在大多数情况下,属性顺序并不重要。因此,我认为,发动机优化,可能会搞砸它是了不起的

但是,如果能有一个替代的sObject,我们可以用它做一些事情,比如:

var x = new sObject({b: 23, a: 7});
…并且相信我们可以以相同的顺序迭代它,或者,也/至少,对它执行一些排序任务,并且相信这不会被改变

当然我正在使用本机javascript对象对其进行初始分析,因此,事实上,理论上我们不能相信它会正确填充(即使我也无法想象为什么任何引擎优化都会在任何操作之前改变它)

我使用这个符号是为了简洁(而且,我承认),因为我希望,在这种情况下,应该总是有效的(即使我不是很确定)。但是,我们甚至可以稍后对其进行排序(在大多数情况下,我们都会这样做),或者使用其他类型的初始化,例如提供一个JSON字符串或具有单个键和值对的对象数组(或数组)

我担心的是:这样的事情还存在吗?我没能找到它。但我肯定不是第一个这么想的人

我可以尝试实现它(我正在考虑)。我认为这是可能的,我可以做到。但这并不是那么简单,所以首先我想确定我没有重新发明轮子


因此,任何意见、建议等。。。欢迎光临。

当然,你可以做到这一切。您将需要一些机器,例如
Object.observer
,它目前仅在Chrome中可用。我们可以将其定义如下:

function myObject(object) {

  // if the object already has keys, bring them in in whatever order.
  var keys = Object.keys(object);

  // Override Object.keys to return our list of keys.
  Object.defineProperty(object, 'keys', { get: function() { return keys; });

  // Watch the object for new or deleted properties.
  // Add new ones at the end, to preserve order.
  Object.observe(object, function(changes) {
    changes.forEach(function(change) {
      if (change.type === 'add') keys.push(change.name);
      if (change.type === 'delete') keys = keys.filter(function(key) {
        return key === change.name;
      });
    });
  });

  return object;
}
请注意,
Object.observe
是异步的,因此即使在向对象添加属性之后,它也不会反映在自定义的
属性中,直到时钟滴答一声之后,尽管理论上可以使用
Object.deliverChangedRecords

上述方法使用一个函数,将新的有序键功能添加到现有对象中。当然,还有其他的设计方法


这个“解决方案”显然无法控制
循环中的
for…的行为。

您是否意识到ES6指定按键添加到对象的顺序枚举键?我的理解是,这被添加到ES6中,以记录最新ES5JS引擎中的现有行为。但是,没有简单的方法可以改变顺序。我可能建议你更容易在你的问题中找到问题。就目前的情况而言,你希望人们在最终找到问题所在之前进行大量阅读。同样,在你的问题中使用这个词也不合适。也许你只是指“Javascript对象”或“Javascript文本”。@jfriend00,我知道这对新的来说是肯定的,但对对象来说是一样的吗?@Andy-是的,它是为ES6中的对象指定的。