Javascript数组对象的行为

时间:2010-12-05 15:48:25

标签: javascript

function map(f, a) {
  for(var i in a) {
    a[i] = f(a[i]);
  }
}

var a = [0, 1, 2, 3];
map(function(x) { return x = x * x }, a);
console.log(a);

a:[0, 1, 4, 9]

但是,如果我将map(f, a)更改为:

function map(f, a) {
  for(var i in a) {
    f(a[i]);
  }
}
var a = [0, 1, 2, 3];
map(function(x) { return x = x * x }, a);
console.log(a);

a保持不变为:[0, 1, 2, 3]

我不确定这里发生了什么。似乎解释器将a[i]视为对a中对象map(f, a)的属性的引用,但一旦传入f,它就变成typeof number

4 个答案:

答案 0 :(得分:1)

这是正确的行为,a[i]被传递到f([i]),而不是对它的引用,因此x内部是明显的不同的变量/参考。

在第一个版本中你得到的结果仍然不同x函数返回)并将其分配到该数组位置......这是唯一的方法使用新的来获取某些东西。

答案 1 :(得分:1)

不要在数组上使用for(... in...)。使用for loop

for in的枚举订单 NOT 保证。它还将遍历属性(不是内置的ins,而是由JS代码设置的东西)和原型上的东西,然后所有地狱都会松动。

接下来,除了数组和对象之外的所有值都是按值传递(基本上数组和对象也按值传递,但值是指向对象的指针)。

所以你不是在这种情况下修改数组中的值,而是局部变量x恰好具有相同的值。

return x = x * x这项任务是多余的。

修正版

function map(f, a) {
  for(var i = 0, l = a.length; i < l; i++) {
    a[i] = f(a[i]);
  }
}

var a = [0, 1, 2, 3];
map(function(x) { return x * x }, a);
console.log(a);

答案 2 :(得分:0)

这个电话:

a[i] = f(a[i]);

实际上与此类似:

var arg = a[i];
var res = f(arg);
a[i] = res;

这称为“按值调用”,请参见此处:

答案 3 :(得分:0)

JavaScript中的数组是对象,而对象总是引用类型。

直到地图函数中存在a的点,您已将其作为整个数组传递,这意味着您对a所做的更改将在外部可见。

使用a[i]取消引用数组后,您有一个Number类型的变量,它不是引用类型。因此,匿名函数中对x的更改不会传播回数组,只能在匿名函数本身中显示。