停止对象的 js 间隔

stopping a js interval for an object

谁能告诉我为什么这段代码不能按我预期的方式工作?

function npc(name) {
  this.name = name;
  this.grid = [[0,9], [0,9]];
  this.position = [0,0];
  this.start = setInterval(function(){this.move() }, 1000);
  this.stop = function(){clearInterval(this.start)};
  this.move = function() {
      this.position[0] = this.position[0] + Math.floor(Math.random() * 2);
      this.position[1] = this.position[1] + Math.floor(Math.random() * 2);
      if (this.position[0] > this.grid[0][1] || this.position[1] > this.grid[1[1]) {
      this.position = [0,0];
  };
  console.log(this.name + " moved to " + this.position);  
  }
};

npc();
var bug = new npc("test-name");
bug.start();
bug.stop();

Bug.start() 不会 运行 除非我先执行 npc() ,但即便如此它也会将 undefined 记录为 name 并且不会停止使用 bug.stop()

对不起,如果这是基本的东西,但我无法自己解决...

试试这个。

function npc(name) {
  this.name = name;
  this.grid = [[0,9], [0,9]];
  this.position = [0,0];
  var that=this;
  this.start = setInterval(function(){that.move() }, 1000);
  this.stop = function(){clearInterval(this.start)};
  this.move = function() {
      this.position[0] = this.position[0] + Math.floor(Math.random() * 2);
      this.position[1] = this.position[1] + Math.floor(Math.random() * 2);
      if (this.position[0] > this.grid[0][1] || this.position[1] > this.grid[1[1]]) {
      this.position = [0,0];
  };
  console.log(this.name + " moved to " + this.position);  
  }
}

这会更改 setInterval 中的上下文。

就在这个函数定义之后 通话

var bug = new npc("test-name");

它显示了一些控制台 O/p 之类的 测试名称移至 1,0 测试名称移至 2,0

您遇到的问题是 this 在您的代码中的不同位置。 setIntervalwindow 对象上的函数,因此 this 是对 window 的引用。但是不要相信我的话! console.log(this) 自己看看吧!

下面的解决方案是解决问题的一种方法。注意将 this 设置为 that。以及将 bug 绑定到此......

<script>
  var Npc = function(name) {
    this.name = name;
    this.grid = [[0,9], [0,9]];
    this.position = [0,0];
  }

  Npc.prototype.start = function() {
    if(this.interval) {
      clearInterval(this.interval);
    }

    this.interval = setInterval(function(that) {
      that.move();
    }, 100, this);
  }


  Npc.prototype.stop = function() {
    if(this.interval) {
      clearInterval(this.interval);
    }
  }

  Npc.prototype.move = function() {
    this.position[0] = this.position[0] + Math.floor(Math.random() * 2);
    this.position[1] = this.position[1] + Math.floor(Math.random() * 2);
    if (this.position[0] > this.grid[0][1] || this.position[1] > this.grid[1][1]) {
      this.position = [0,0];
    };
    console.log(this.name + " moved to " + this.position);
  }


  var bug = new Npc("test-name");
  bug.start();
  setInterval(bug.stop.bind(bug), 5000);
</script>

虽然给定的解决方案可以正常工作,但还有另一个解决方案使用了引入的想法 here:

您只需像这样更改 start 变量:

this.start = function() {
setInterval(
  (function(self) {
  return function() {
    self.move();
    }
   })(this), 1000);
}

为了演示如何使用此方法使用 start()stop() 函数,我创建了一个 fiddle。请注意,您可以通过单击按钮或在 setInterval() 函数中定义一些条件来停止。

例如,如果你想在第二个位置达到 1 时停止错误:

this.handle; //To keep timer handle
this.start = function() {
this.handle = setInterval(
    (function(self) {
    return function() {
      self.move();
      if(self.position[1]==1) self.stop(self.handle); //Stop on some condition   
      }
    })(this), 1000);
  };
  this.stop = function(handle) {
      console.log("time to stop");
      clearInterval(handle);
    }