Javascript中嵌套函数的返回值

IT技术 javascript function nested return-value return
2021-03-13 21:33:35

我有一个功能设置如下

function mainFunction() {
      function subFunction() {
            var str = "foo";
            return str;
      }
}

var test = mainFunction();
alert(test);

按照我的逻辑,该警报应该返回“foo”,但它返回未定义。我究竟做错了什么?

更新:这是我的实际代码(它是使用 Google API 进行反向地理编码的函数)

function reverseGeocode(latitude,longitude){
    var address = "";
    var country = "";
    var countrycode = "";
    var locality = "";

    var geocoder = new GClientGeocoder();
    var latlng = new GLatLng(latitude, longitude);

     return geocoder.getLocations(latlng, function(addresses) {
     address = addresses.Placemark[0].address;
     country = addresses.Placemark[0].AddressDetails.Country.CountryName;
     countrycode = addresses.Placemark[0].AddressDetails.Country.CountryNameCode;
     locality = addresses.Placemark[0].AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.LocalityName;
     return country;
    });   
   }
3个回答

您必须先调用函数才能返回任何内容。

function mainFunction() {
      function subFunction() {
            var str = "foo";
            return str;
      }
      return subFunction();
}

var test = mainFunction();
alert(test);

或者:

function mainFunction() {
      function subFunction() {
            var str = "foo";
            return str;
      }
      return subFunction;
}

var test = mainFunction();
alert( test() );

对于您的实际代码。返回应该在外部,在主函数中。回调在getLocations方法内部的某个地方被调用,因此它的返回值不会在您的主函数中收到。

function reverseGeocode(latitude,longitude){
    var address = "";
    var country = "";
    var countrycode = "";
    var locality = "";

    var geocoder = new GClientGeocoder();
    var latlng = new GLatLng(latitude, longitude);

    geocoder.getLocations(latlng, function(addresses) {
     address = addresses.Placemark[0].address;
     country = addresses.Placemark[0].AddressDetails.Country.CountryName;
     countrycode = addresses.Placemark[0].AddressDetails.Country.CountryNameCode;
     locality = addresses.Placemark[0].AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.LocalityName;
    });   
    return country
   }
谢谢。问题在于,当我简单地输入返回国家时;它返回“”,因为我通常没有足够快地从谷歌收到信息。有没有办法让它等到值改变?
2021-04-30 21:33:35
getLocations是异步的。那个代码不能用。
2021-05-07 21:33:35
你错过了我最喜欢的选择 return (funtion(){...})();
2021-05-09 21:33:35
我已经用实际代码更新了我的问题。我遇到的问题是我正在使用 Google API,所以我的子函数正在被他们的一个函数调用。任何想法我将如何解决它?
2021-05-10 21:33:35
@chris 我认为使用这些 API 的更好方法是将您的逻辑(您想对国家/地区、地址 .. 做的事情)放在回调中。
2021-05-17 21:33:35

对。您传递给 getLocations() 的函数在数据可用之前不会被调用,因此在设置之前返回“国家/地区”对您没有帮助。

您需要这样做的方法是让您传递给 geocoder.getLocations() 的函数实际上执行您想要对返回值执行的任何操作。

像这样的东西:

function reverseGeocode(latitude,longitude){
  var geocoder = new GClientGeocoder();
  var latlng = new GLatLng(latitude, longitude);

  geocoder.getLocations(latlng, function(addresses) {
    var address = addresses.Placemark[0].address;
    var country = addresses.Placemark[0].AddressDetails.Country.CountryName;
    var countrycode = addresses.Placemark[0].AddressDetails.Country.CountryNameCode;
    var locality = addresses.Placemark[0].AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.LocalityName;
    do_something_with_address(address, country, countrycode, locality);
  });   
}

function do_something_with_address(address, country, countrycode, locality) {
  if (country==="USA") {
     alert("USA A-OK!"); // or whatever
  }
}

如果您可能想在每次获取位置时执行不同的操作,则将该函数作为附加参数传递给 reverseGeocode:

function reverseGeocode(latitude,longitude, callback){
  // Function contents the same as above, then
  callback(address, country, countrycode, locality);
}
reverseGeocode(latitude, longitude, do_something_with_address);

如果这看起来有点乱,那么您可以看看 Dojo 中的 Deferred 特性之类的东西,它使函数之间的链接更加清晰。

谢谢,但是我遇到的问题是我想在整个代码中多次使用 reverseGeocode。我有一个从 twitter API 返回的状态更新及其位置的列表,因此我想为每个更新调用 reverseGeocode。另外,我想为当前用户的位置调用 reverseGeocode。不确定这是否有意义......如果你想看看我的意思,该网站位于chris-armstrong.com/whispers
2021-04-26 21:33:35
如有疑问,请使用更多功能:-) 请参阅上面的编辑...
2021-05-01 21:33:35

仅供参考,地理编码器是异步的,因此在这种情况下,逻辑上的公认答案实际上不起作用。我希望有一个外部对象作为您的更新程序。

var updater = {};

function geoCodeCity(goocoord) { 
    var geocoder = new google.maps.Geocoder();
    geocoder.geocode({
        'latLng': goocoord
    }, function(results, status) {
        if (status == google.maps.GeocoderStatus.OK) {
            updater.currentLocation = results[1].formatted_address;
        } else {
            if (status == "ERROR") { 
                    console.log(status);
                }
        }
    });
};