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