请原谅模糊的标题。我不确定是什么导致了这个问题,而且不能更具体。
我有两个连续的函数调用,其中第一个函数是“弄乱”我的第二个函数中的变量。虽然在我看来,所有变量都是其功能的本地变量。
var data = [
'Science Fiction',
'Business / Management',
'Business / Management / Leadership',
];
function getName(parts) {
return parts[parts.length - 1];
}
function getTrail(parts) {
if (parts.length === 1) return null;
parts.pop();
return parts.join(' / ');
}
function getParents(parts) {
if (parts.length === 1) return null;
parts.pop();
return parts;
}
function generate(path) {
var parts = path.split(' / ');
return {
name: getName(parts),
trail: getTrail(parts), // <= Problem?
parents: getParents(parts) // <= Last part is missing when getTrail(parts) is called before.
};
}
var categories = data.map(generate);
请参阅 http://jsfiddle.net/n6Dud/ ,了解更好的间隔和工作示例。
运行示例时,您可以检查控制台并查看object.parents
中的最后一部分是否丢失。我怀疑来自parts.pop()
的{{1}}。
为什么会这样,我该如何解决呢?
答案 0 :(得分:1)
getTrail
弹出parts
的最后一个元素,因为parts
是对原始数据的引用,即使在函数返回后,更改也是可见的。
您需要通过操作parts
的副本来使操作具有非破坏性。这可以使用slice
来完成除最后一个元素之外的所有内容的复制:
if (parts.length === 1) return null;
return parts.slice(0, -1).join(' / ');
答案 1 :(得分:0)
当您在JavaScript中传递数组时,您实际上是将引用传递给该数组,而不是它的副本。
因此,对该阵列的任何修改也会修改原件。如果您想确保不修改原件,您应该自己复制,例如:
var copy = parts.slice(0);
因为碰巧你不想要副本的最后一个元素,你可以在复制时删除它:
var copy = parts.slice(0, -1);
答案 2 :(得分:0)
要使其工作,您需要克隆对象(这意味着您必须将其所有属性复制到另一个对象)以确保您正在编辑的对象是另一个对象。对象的行为与其他数据类型(如字符串)不同。对于对象,变量保存对象引用,而不保存对象本身。这使得将对象传递给另一个函数,然后在另一个函数中编辑该对象,您还将编辑原始对象。
您可以通过简单的forloop复制对象:
function cloneObj(o) {
var clone = {};
for (var i in o) {
if (typeof o[i] === 'object') clone[i] = cloneObj(o[i]);
else clone[i] = o[i];
}
}
或对于数组,使用Alnitak提到的方法:
var copied = parts.slice(0);