array.push()仅包含循环的最终值

时间:2017-03-28 16:12:49

标签: javascript arrays typescript

我有以下JavaScript(Typescript)示例,其中我初始化一个数组,然后推送每小时的时间戳,直到该范围中包含end时间戳。

let res = [start];
while (res[res.length - 1].isBefore(end)) {
    let nextTime = res[res.length - 1].add(1, 'hour'); // add one hour to the previous result - this is a moment.js instance
    console.log('loop', nextTime.format())
    res.push(nextTime);
}
res.forEach(val => console.log('result', val.format()))

循环中的console.log会记录预期值,例如

  

循环2017-03-27T18:00:00 + 01:00

     

循环2017-03-27T19:00:00 + 01:00

     

循环2017-03-27T20:00:00 + 01:00

但是,结果数组似乎只包含正确数量的记录,但它们都是最终值,例如

  

结果2017-03-28T18:00:00 + 01:00

     

结果2017-03-28T18:00:00 + 01:00

为什么会这样?

1 个答案:

答案 0 :(得分:5)

MomentJS对象是具有状态的可变(可更改)对象。在MomentJS对象上调用add会修改它,但不会创建新对象;它只返回对同一对象的引用。所以说你从这开始:

     +−−−−−−−−−+        
res−>| (array) |        
     +−−−−−−−−−+        +−−−−−−−−−−+    
     | 0       |−−−−−−−>| (object) |    
     +−−−−−−−−−+        +−−−−−−−−−−+   +−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ 
                        | d:       |−−>|                  (Date)                  | 
                        +−−−−−−−−−−+   +−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ 
                                       | [[TimeValue]]: 2017−03−27T18:00:00+01:00 |
                                       +−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+

你的

let nextTime = moment(res[res.length - 1]).add(1, 'hour');
// ...
res.push(nextTime);

修改该对象并将其另一个引用推送到res

     +−−−−−−−−−+        
res−>| (array) |        
     +−−−−−−−−−+        +−−−−−−−−−−+   
     | 0       |−−−−+−−>| (object) |   
     | 1       |−−−/    +−−−−−−−−−−+   +−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+
     +−−−−−−−−−+        | d:       |−−>|                  (Date)                  |
                        +−−−−−−−−−−+   +−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+
                                       | [[TimeValue]]: 2017−03−27T19:00:00+01:00 |
                                       +−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+

注意对象的状态(MomentJS对象使用的Date中的[[TimeValue]]如何变化。

如果再次执行此操作,我们只需再次更新:

     +−−−−−−−−−+        
res−>| (array) |        
     +−−−−−−−−−+        +−−−−−−−−−−+   
     | 0       |−−−−+−−>| (object) |   
     | 1       |−−−/    +−−−−−−−−−−+   +−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+
     | 2       |−−/     | d:       |−−>|                  (Date)                  |
     +−−−−−−−−−+        +−−−−−−−−−−+   +−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+
                                       | [[TimeValue]]: 2017−03−27T20:00:00+01:00 |
                                       +−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+

相反,您想要创建一个新对象。你可以用moment克隆原文来做到这一点。

let nextTime = moment(res[res.length - 1]).add(1, 'hour');
// ------------^^^^^^^   ----------------^
// ...
res.push(nextTime);

如果你这样做,那么从同一个起点,我们得到:

     +−−−−−−−−−+        
res−>| (array) |        
     +−−−−−−−−−+        +−−−−−−−−−−+   
     | 0       |−−−−−−−>| (object) |   
     | 1       |−−−−+   +−−−−−−−−−−+   +−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+
     | 2       |−−+ |   | d:       |−−>|                  (Date)                  |
     +−−−−−−−−−+  | |   +−−−−−−−−−−+   +−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ 
                  | |                  | [[TimeValue]]: 2017−03−27T18:00:00+01:00 | 
                  | |   +−−−−−−−−−−+   +−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ 
                  | +−−>| (object) |                                                
                  |     +−−−−−−−−−−+   +−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ 
                  |     | d:       |−−>|                  (Date)                  |
                  |     +−−−−−−−−−−+   +−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ 
                  +−−−−>               | [[TimeValue]]: 2017−03−27T19:00:00+01:00 | 
                        +−−−−−−−−−−+   +−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ 
                        | (object) |                                                
                        +−−−−−−−−−−+   +−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ 
                        | d:       |−−>|                  (Date)                  |
                        +−−−−−−−−−−+   +−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+
                                       | [[TimeValue]]: 2017−03−27T20:00:00+01:00 |
                                       +−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+