【发布时间】:2013-03-30 16:34:21
【问题描述】:
我最近在 JS 中遇到了一个令人讨厌的问题。
假设我们将一个映射、一个对象数组传递给函数 f。
var o=[{a:0}];
function f(a){
for(var i in a){
if (a.hasOwnProperty(i)){
a[i]=null;
}
}
return a;
};
var outp=f(o);
alert(outp[0]+" === "+o[0]+" : "+(outp[0]===o[0]));
// here we expect loose equality, and equality in type,
//furthermore it should identically equal as well, and we got right!
但是,我们不能将对象的全部责任作为参数传递给函数,就像在函数范式 o=(function(o){return o})() 中一样,因为对 o 的任何修改都不会被引用!
var o=[];
function ff(a){
return (a=undefined);
};
var outp=ff(o);
alert(outp+" === "+o.constructor+" : "+(outp===o));
// here we expect true, but we got false!
为什么上面描述的参考损失和 在第二个用例中可能有不同的参考处理, 虽然在这两种情况下,函数都将数组参数放在 0. 位置?
【问题讨论】:
-
您只需为 local 变量
a分配一个新值。您不会修改它引用的值。在 JavaScript 中,一切都是按值传递的,而不是通过引用传递(在对象和数组的情况下,“值”是对对象和数组的引用,而不是对持有引用的变量的引用)。这在其他语言中也是类似的,例如Python 和 Java。 -
您不应该使用
for-in-loops 遍历数组,即使您使用hasOwnProperty。 -
@Bergi 是对的。我的意思是如果你想这样做,没有人会阻止你,但这不仅仅是保持你的结构干净的问题(如果你这样做,我不知道你为什么使用
.hasOwnProperty()首先)。for-in不保证任何特定的枚举顺序。还有性能影响。.length肯定是拥有的财产,尽管它也存在于原型链中。 -
...如果这篇文章归结为“我希望 JavaScript 与众不同...”,那么,加入俱乐部吧。
-
@ZoltanLudanyi:是的,如果
for-in在数组上使用时保证顺序,那看起来会很好。但是请记住,JavaScript 数组只是一种特殊的对象(数组索引与对象上的属性没有什么不同),因此保证不存在是有逻辑的。一群非常聪明的人的欲望对订单没有保证的现实没有影响。我们可以终其一生都希望事情有所不同,或者我们可以自己变得聪明,并以他们预期和指定的方式使用我们提供的工具......并避免.hasOwnProperty()hack的成本。
标签: javascript arrays ecmascript-5 ecma262