【问题标题】:argumental reference inconsistency in javascriptjavascript中的参数引用不一致
【发布时间】: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


【解决方案1】:

Javascript 总是按值传递参数,所以这不起作用:

 function foo(x) {
    x = 100;
 }

 y = 5
 foo(y)
 y == 100 // nope

但这确实有效:

 function foo(x) {
    x.bar = 100;
 }

 y = {}
 foo(y)
 y.bar == 100 // yes

在第二个 sn-p x 中仍然是按值传递的,但是这个值是一个对象的引用(指针)。因此,可以在函数中取消引用它并访问对象“内部”的内容。

【讨论】:

  • ES5 规范应该提供方法来指定我是要传递值还是引用函数,因为 PHP 中提供了选项!
  • @ZoltanLudanyi:“通过引用传递”很少是一个好主意。理想情况下,函数应该避免副作用,并且默默地修改调用者的作用域可能是最糟糕的副作用。
  • @ZoltanLudanyi:不。JavaScript 只是不允许通过引用传递。函数调用在 ES5 中被指定为按值调用。你需要它做什么?
  • JS 提供了很多功能性的设施。我相信,仅按值传递的参数(例如引用豆袋)确实是不好的部分之一!
  • @Zoltan:许多语言不允许这样做,但它们非常强大和流行,例如Python。你当然可以有你的意见,但 SO 是讨论它的错误地方。
猜你喜欢
  • 1970-01-01
  • 2019-05-29
  • 2020-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-19
  • 1970-01-01
相关资源
最近更新 更多