【问题标题】:Why javascript "for loop" has different behaviours for different type of objects为什么javascript“for循环”对不同类型的对象有不同的行为
【发布时间】:2018-01-29 08:26:14
【问题描述】:

我意识到 JavaScript 没有指针,但是我在循环包含对象的数组时注意到了这种“指针”行为,但在数组包含数字时(例如)却没有类似的行为。

var ARR_num = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
for (var i = 0, len = ARR_num.length; i < len; i++) {
  var item = ARR_num[i];
  item++;
}
console.log(ARR_num);
//Outputs [0,1,2,3,4,5,6,7,8,9]

现在有一个包含对象的数组

var ARR_obj = [{}, {}, {}];
for (var i = 0, len = ARR_obj.length; i < len; i++) {
  var item = ARR_obj[i];
  item.pointer = true;
}
console.log(ARR_obj);
//Outputs [{pointer: true}, {pointer: true}, {pointer: true}]

为什么会有这两种截然不同的行为?

【问题讨论】:

  • 因为item === ARR_obj[i]item 指的是 ARR_obj[i]
  • 这是因为 javascript 将整数作为值传递,而将对象作为引用传递(实际上是引用的值是精确的)。这意味着当你将它存储在item中时,对item所做的更改会影响原始对象,但不会影响原始整数
  • for 循环在您的示例中没有不同的行为 - 这是您对数组中的数据所做的不同
  • @Rajesh 虽然我可以理解,但我的问题可能是重复的,指出的问题并没有完全回答 primitives 部分。

标签: javascript pointers scope closures var


【解决方案1】:

为什么会有这两种截然不同的行为?

当您将 对象 分配给另一个变量时,新变量指向相同的对象,因此当您更改新变量属性时,对象会发生变异 示例:

var a= {name: "some"};
var b = a;
b.name = "newName";
console.log(a.name);// "newName"

当您将 原始类型 分配给另一个变量时,它只是一个新变量并且没有引用旧变量,因此更改新变量不会影响旧变量。 示例:

var a = "some";
var b = a;
b = "newName";
console.log(a);//"some"

希望这会有所帮助!

【讨论】:

    【解决方案2】:

    我们知道,所有值(不是原始值)都是对象指针。 所以 item 在用例 2 中是一个对象指针,而在用例 1 中它是整数。

    在用例 2 中,它指的是所有迭代的值“true”。所以根据编写的代码给出正确的结果。

    一般JavaScript不支持通过引用传递参数,所以在Javascript中使用Objects,我们可以传递引用。

    【讨论】:

      【解决方案3】:

      为什么会有这两种截然不同的行为?

      因为您有两个不同的操作。在后者中,您正在改变对象的状态

      item.pointer = true;
      

      item 一直指向同一个对象。仅更改对象的内部结构。

      这里

      item++; # equivalent to item = item + 1
      

      重新分配项目。操作后它将指向另一个整数。如果在对象循环中做类似的操作

      item = { pointer: true }
      

      那么你的原始数组元素不会受到影响,你也不会观察到任何“指针语义”。

      是的,它也与作为原始/立即值的整数有关。

      【讨论】:

        【解决方案4】:

        {} 是对象文字语法,它在数组中创建(在您的情况下)新对象。当遍历它并使用 ARR_obj[i] 时,您会得到引用的对象,然后对其进行操作。

        或者用其他(更一般的)词来表达:

        基元(未定义、空值、布尔值、字符串和数字)通过值传递,而对象通过引用传递(或者更准确地说是引用的副本)。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-09-05
          • 2022-12-04
          • 1970-01-01
          • 2013-06-26
          • 2018-10-11
          • 2021-07-11
          • 2011-08-16
          • 1970-01-01
          相关资源
          最近更新 更多