You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript循环向对象数组push元素仅最后一项生效问题

问题根本原因

两个核心问题共同导致了你遇到的异常:

  1. 对象引用传递特性:JavaScript中对象属于引用类型,你在循环外预先声明了唯一的this.locationObject空对象,后续循环中每次修改属性、push到数组的操作,本质上都是在操作同一个内存地址的对象,数组中存储的所有元素都只是指向这一个对象的引用。循环执行完成后,这个对象的属性是最后一次循环赋值的结果,自然所有数组项看起来都被最后一次的值覆盖。
  2. 异步回调的上下文错位:你尝试在循环开头重置that.locationObject = {}的方案,确实解决了引用共享的问题,但Ajax的success回调是异步执行的——等所有请求触发回调时,for循环早已执行完毕,此时that.locationObject已经指向了最后一次循环创建的新对象。所有回调执行时都会给这最后一个对象赋值pos属性,之前循环中push进数组的独立对象根本没有被设置pos,最终就出现了tooltip、type正常但pos缺失的问题。
可直接运行的修复代码

核心调整思路:每次循环创建独立的局部对象,通过闭包让每个Ajax回调绑定到当前迭代对应的对象上,不要在实例this上挂载共享的临时对象。

this.locationObjectArray = [];
var that = this;

oModel.read("/Customers", {
  success: function (resp) {
    var promises = [];
    // 移除循环外的共享locationObject声明,不要在this上挂载临时对象
    for (var x = 0; x < resp.results.length; x++) {
      // 每次循环创建独立的当前位置对象,用局部变量存储
      var currentLocation = {
        tooltip: resp.results[x].Country,
        type: "Inactive"
      };

      // 发起地理编码请求
      var request = $.ajax({
        url: "https://api.opencagedata.com/geocode/v1/json?key=d3e40bf9b50247d4acf8122c543c5187&q=" + currentLocation.tooltip,
        type: "GET",
        dataType: 'json',
        // 闭包直接持有当前循环的currentLocation引用,不会出现上下文错位
        success: function (geoResp) {
          currentLocation.pos = geoResp.results[0].geometry.lng + ";" + geoResp.results[0].geometry.lat + ";0";
        }
      });

      // 推入当前独立对象、收集promise
      that.locationObjectArray.push(currentLocation);
      promises.push(request);
    }

    // 所有请求完成后再更新模型
    $.when.apply(null, promises).done(function(){
      that.getView().getModel("map").setProperty("/Spots", that.locationObjectArray);
    })
  }
})
额外优化建议
  • 如果你的运行环境支持ES6语法,可以把循环中的var x改成let x,配合let的块级作用域特性,可以进一步避免循环变量的上下文共享问题
  • 不建议把流程中用到的临时中间对象挂载到组件实例this上,临时变量用函数内局部变量存储即可,避免全局污染和意外的引用篡改
  • 可以给Ajax请求增加错误回调,避免某一个地理编码请求失败导致整个$.when链直接挂掉

内容的提问来源于stack exchange,提问作者SeventhWarhawk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 06:09:33