首页 文章

Javascript:从内部对象方法调用的回调函数产生意外结果

提问于
浏览
-1

我有一个名为RouteLeg的简单对象,它包含一组Lat / Lng值,并且能够使用google maps api在两个lat / lng点之间渲染一条行车路线 .

在renderRoad方法中,我调用google maps api DirectionsService.route方法,在回调函数上使用闭包,以便它可以访问RouteLeg对象(self是定义为self = this的对象成员):

directionsService.route(request, (function(obj) {
    return function(result, status) {
        if (status == google.maps.DirectionsStatus.OK) {
            obj.getDisplay().setDirections(result);
        }
    };
})(self));

仅当RouteLeg的 display 成员变量(DirectionsRenderer对象)声明为私有(var display)而不是public(this.display)时,代码才有效 . 当display被声明为public时,它在回调函数中的值总是为null .

我是JS的新手,并不理解这种行为 . 我错过了什么?

(P.S.当我改变显示变量的范围时,我也改变this.getDisplay函数来匹配.directionService和map是全局变量) .

function RouteLeg(aStart, aEnd) {
  var start = aStart; //an object that contains lat/lng values
  var end = aEnd; //lat/lng object
  this.display = null;  //does not work, only works as when declared as a var 
  var self = this;

  this.getDisplay = function() {
    return this.display;
  }

  this.render = function() {
    renderRoad();
  }

  var renderRoad = function() {
    if (this.display == null) {
      this.display = new google.maps.DirectionsRenderer({
        suppressMarkers: true
      });
    }
    this.display.setMap(map);

    var request = {
      origin: new google.maps.LatLng(start.getLat(), start.getLng()),
      destination: new google.maps.LatLng(end.getLat(), end.getLng()),
      travelMode: google.maps.TravelMode.DRIVING
    };

    //directionsService is a global variable for now
    directionsService.route(request, (function(obj) {
      return function(result, status) {
        if (status == google.maps.DirectionsStatus.OK) {
          obj.getDisplay().setDirections(result);
        }

      };
    })(self));

  }
}

2 回答

  • 0

    发生这种情况是因为renderRoad没有RouteLeg的执行上下文 . 在执行 renderRoad 时的含义, this 指的是全局对象而不是RouteLeg的实例 .

    为了使其工作,要么在RouteLeg实例上定义renderRoad:

    this.render = function() {
      this.renderRoad();
    }
    
    this.renderRoad = function() {
    

    或者使用call / bind / apply将renderRoad的执行上下文设置为RouteLeg实例

    this.render = function() {
      renderRoad.call(this);
    }
    
    var renderRoad = function() {
    
  • 0

    在没有上下文的情况下调用renderRoad函数,设置this.display的代码将其设置在另一个对象上,然后是self传递的对象 .

    renderRoad.apply(this)
    

相关问题