Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/14.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_Node.js - Fatal编程技术网

Javascript 在迭代对象的键时重命名它们是否安全?

Javascript 在迭代对象的键时重命名它们是否安全?,javascript,json,node.js,Javascript,Json,Node.js,我在迭代对象的键时重命名它们: Object.keys(object).forEach(function(oldKey) { var newKey = someFunc(oldKey); if (newKey !== oldKey) { object[newKey] = object[oldKey]; delete object[oldKey]; } } 我想知道这种方法是否安全 换句话说,我可以确保我的代码永远不会迭代在上一次迭代中重命

我在迭代对象的键时重命名它们:

Object.keys(object).forEach(function(oldKey) {
    var newKey = someFunc(oldKey);
    if (newKey !== oldKey) {
        object[newKey] = object[oldKey];
        delete object[oldKey];
    }
}
我想知道这种方法是否安全

换句话说,我可以确保我的代码永远不会迭代在上一次迭代中重命名的键吗?

对象。键与许多其他方法一样,返回可以迭代的数组。此数组不是“活动”数组,而是拍摄时的快照(例如,执行
Object.keys
)。因此,是的,您可以按预期使用它

很少有方法返回“实时列表”而不是数组;我想您已经记住了,当您使用document.queryselectoral时会得到。然而,这不是一个数组,而是一个节点列表


然而,我可以看到一个陷阱:当一个生成的newKey已经存在于oldkey列表中时(不是当前的!)。因此,您可以或不可以(取决于数组中的位置)迭代已覆盖的新密钥。

不,您不安全。您正在基于非活动数组对对象进行活动变异。如果你碰巧将一个新名字与一个旧名字交叉(将a重命名为b,但b已经存在,而且还没有到达),你会过得很糟糕

您不会遇到已经看到的键,但无法知道对象中是否尚未找到
newKey

有一些变通方法,这种情况类似于迭代数组时对数组进行加密(删除元素),简单的变通方法是向后迭代,以便始终传递修改过的键。(或者在您的情况下,请与
操作员中的
进行检查)

但是,创建并返回新对象会更好:

const newObj = Object.keys(object).reduce(function(result, oldKey) {
    var newKey = someFunc(oldKey);
    return { ...result, [newKey]: object[oldKey] };
}, {});

如果您将所有数据结构视为不可变的(更具体地说,当密钥从未更改时),您可以免费获得很多东西。

下面是一个在不创建新对象的情况下更改密钥的解决方案

for(key in obj){          
    Object.defineProperty(obj, `myNewName`, Object.getOwnPropertyDescriptor(obj, key));
    delete obj[key];
}

你自相矛盾。这最后一点正是为什么答案是,你不安全的变异对象作为OP提出。这个问题不必与DOM,但我想我会澄清一些东西,现在删除的答案说。它错误地指出
querySelectorAll
返回一个实时列表。有动态和静态版本的
NodeList
querySelectorAll
实际上返回一个静态(非活动)节点列表。一些较旧的DOM接口,如
Node.childNodes
返回一个活动的
NodeList
,同样,一些较旧的接口,如
getElementsByTagName
返回一个始终活动的
HTMLCollection
。如果文档中说它返回了一个
数组
(像'Object.keys那样),那么该数据是非活动的。非常感谢。如果我确信我永远不会生成一个已经存在的密钥呢?我发布的代码中并没有保证这一点,因为
someFunc
似乎对
object
一无所知,但让我们假设情况确实如此(因为在我的完整程序中是这样的)。那么我安全了吗?@Goodscibration根据我的经验,问题是这个假设在今天是正确的,但在将来不会是正确的,到那时,代码中假设的存在将被忘记,你很难找到/调试bug。没有理由不在这里创建一个新对象,性能增益可以忽略不计。我不认为我在创建一个新对象。你是对的@goodvibration。但带“.reduce”的答案是正确的。我并不是说我的答案更好,我只是想展示一种不同的方法:-)好的,但您可能应该在代码中将
中的“myNewName”
更改为
someFunc(key)