【问题标题】:Understanding of namespace in JavaScript [duplicate]理解 JavaScript 中的命名空间 [重复]
【发布时间】:2019-03-05 10:15:35
【问题描述】:

虽然我确实有一些 Python 编程经验,但我对 JavaScript 还是很陌生。 我的问题是,我似乎不理解 JS 中命名空间的概念,因为它似乎与 Python 中的不同。这是我的代码:

    function snake(x, y) {
      // x and y coordinate of square (topleft)
      this.x = x;
      this.y = y;

      // reference to div object 'box2'
      this.boxid = "#box";
      this.box = document.getElementById(this.boxid);

      // attempts to move the box by args
      this.move = function (speedx, speedy) {
        var m = 50;
        // check if the box is within the container, moves if true
        if ((this.x+(speedx*m))<=150 && (this.y+(speedy*m))<=150 &&
        (this.y+(speedy*m))>=0 && (this.x+(speedx*m))>=0) {
          this.x = this.x + speedx*m;
          this.y = this.y + speedy*m;
        }
      }

      // called every frame to update position of the box
      this.update = function () {
        $(this.boxid).css({top: this.y, left: this.x});
      }
    }

    var snakeObj = new snake(100, 100);
    var t = setInterval(s.update, 100);

当按下四个箭头键之一时,将使用正确的参数执行 move() 函数。

现在代码显示在那里的方式,JS 告诉我 update() 函数中的 x 和 y 值是“未定义的”。但是,只要我将它们从 this.x 和 this.y 更改为 snakeObj.x 和 snakeObj.y,以及将 this.boxid 更改为“#box”,一切都会完美运行。 我想了解为什么 update() 函数不能“访问”对象中的值,而 move() 函数却完全没问题。

为了澄清,工作代码如下所示:

    function snake(x, y) {
      // x and y coordinate of square (topleft)
      this.x = x;
      this.y = y;

      // reference to div object 'box2'
      this.boxid = "#box";
      this.box = document.getElementById(this.boxid);

      // attempts to move the box by args
      this.move = function (speedx, speedy) {
        var m = 50;
        // check if the box is within the container, moves if true
        if ((this.x+(speedx*m))<=150 && (this.y+(speedy*m))<=150 &&
        (this.y+(speedy*m))>=0 && (this.x+(speedx*m))>=0) {
          this.x = this.x + speedx*m;
          this.y = this.y + speedy*m;
        }
      }

      // called every frame to update position of the box
      this.update = function () {
        $("#box).css({top: snakeObj.y, left: snakeObj.x});
      }
    }

    var snakeObj = new snake(100, 100);
    var t = setInterval(s.update, 100);

【问题讨论】:

  • 我假设s.update 我们应该是snakeObj.update()?问题不在于命名空间,也不在于当您将函数引用传递给 setInterval 时,this 的值不是您认为的那样。您可以尝试使用以下方式显式绑定它:setInterval(snakeObj.update.bind(snakeObj), 100)
  • 与 Python 一样,this 的作用类似于隐式的 self 参数,但与 Python 不同的是,访问 s.update 不会创建绑定方法,而只是给出您仍需要传递的函数实例。

标签: javascript namespaces javascript-namespaces


【解决方案1】:

这是因为你有另一个this 值;用于内部函数的那个​​。

在 JavaScript 中,每个函数都有自己的 this 值。函数是在调用时绑定的,这意味着如果您不通过属性访问调用它们,它们会在没有正确的this 值的情况下调用。一个常见的解决方法是在对象的构造函数中设置var that = this;,这样您就可以通过构造函数中定义的函数的闭包来使用原始值。

如果您不介意放弃对 IE11 的支持,另一种解决方法是使用 ES6 箭头函数,如下所示:

function snake(x, y) {
  // x and y coordinate of square (topleft)
  this.x = x;
  this.y = y;

  // reference to div object 'box2'
  this.boxid = "#box";
  this.box = document.getElementById(this.boxid);

  // attempts to move the box by args
  this.move = (speedx, speedy) => (function (speedx, speedy) {
    var m = 50;
    // check if the box is within the container, moves if true
    if ((this.x+(speedx*m))<=150 && (this.y+(speedy*m))<=150 &&
    (this.y+(speedy*m))>=0 && (this.x+(speedx*m))>=0) {
      this.x = this.x + speedx*m;
      this.y = this.y + speedy*m;
    }
  }).call(this, speedx, speedy);

  // called every frame to update position of the box
  this.update = () => $("#box").css({top: this.y, left: this.x});
}

var snakeObj = new snake(100, 100);
var t = setInterval(s.update, 100);

【讨论】:

  • 非常感谢您的快速回答!它工作得很好,我想我现在更好地理解它了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-01-01
  • 2021-08-26
  • 2011-04-17
  • 2019-07-09
  • 1970-01-01
  • 2015-03-26
相关资源
最近更新 更多