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

无法访问函数返回对象的属性?打印对象正常但属性值为undefined

问题根源:异步操作的执行顺序坑了你!

兄弟,你遇到的这个问题我见太多了——核心原因就是google.maps.Geocoder.geocode()是个异步方法!它不会像普通同步代码那样,调用完立刻给data赋值,而是先把请求发出去,然后直接跳过回调函数继续执行你的其他代码,等谷歌服务器返回地理编码结果后,才会回头执行回调里的赋值逻辑。

给你拆解下代码的实际执行顺序:

  • 创建geocoder实例,初始化空的data对象
  • 调用geocoder.geocode(),向谷歌发送地理编码请求
  • 直接跳出当前函数(或者执行你后面访问data.prop的代码)——这时候data还是个空对象,属性根本没被赋值!
  • 过了几百毫秒(甚至更久),谷歌的响应回来了,才会执行回调里的data.longitude = ...这些赋值操作

至于你打印整个data对象时能看到属性,是因为浏览器控制台会“实时更新”对象内容(其实是你展开对象的时候才去读取最新值),但你同步访问data.prop的那一刻,属性还没被创建,自然就返回undefined了。

解决方案:用Promise/async-await驯服异步逻辑

要解决这个问题,最优雅的方式是把异步操作封装成Promise,这样就能确保你在拿到数据之后再去访问属性:

function geocodeAddress(value) {
  return new Promise((resolve, reject) => {
    const geocoder = new google.maps.Geocoder();
    geocoder.geocode({'address': value}, function(results, status) {
      if (status === 'OK') {
        const locationData = {
          longitude: results[0].geometry.location.lng(),
          latitude: results[0].geometry.location.lat()
        };
        resolve(locationData); // 请求成功,返回数据
      } else {
        reject(new Error(`地理编码失败:${status}`)); // 请求失败,返回错误信息
      }
    });
  });
}

// 调用方式1:用async/await(推荐,代码更像同步逻辑)
async function fetchLocation() {
  try {
    const data = await geocodeAddress("你的目标地址");
    console.log(data.longitude); // 这里就能正常拿到值了!
    console.log(data.latitude);
    // 在这里做你需要的后续操作
  } catch (err) {
    console.error(err.message);
  }
}

// 调用方式2:用.then()链式调用(兼容旧环境)
geocodeAddress("你的目标地址")
  .then(data => {
    console.log(data.longitude);
    console.log(data.latitude);
  })
  .catch(err => console.error(err.message));
简单粗暴的替代方案:在回调内部处理数据

如果你不想折腾Promise,也可以直接把需要用到data的逻辑全部放到回调函数里面——这样就能保证代码是在属性赋值完成后才执行的:

function geocodeAddress(value) {
  const geocoder = new google.maps.Geocoder();
  geocoder.geocode({'address': value}, function(results, status) {
    if (status === 'OK') {
      const data = {
        longitude: results[0].geometry.location.lng(),
        latitude: results[0].geometry.location.lat()
      };
      // 所有需要用data的逻辑都写在这里
      console.log(data.longitude); // 正常输出
      console.log(data.latitude);
      processLocation(data); // 传给其他处理函数
    } else {
      console.error(`地理编码失败:${status}`);
    }
  });
}

function processLocation(location) {
  // 在这里处理你的位置数据
  console.log("处理后的经度:", location.longitude);
}

总结一下:异步操作的结果绝对不能在回调外部同步获取,必须等异步请求完成后再处理数据——Promise+async/await是现在处理异步逻辑最清晰、最易维护的方式,建议优先用这个方案!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 03:46:02