【问题标题】:Javascript objects calling function from itselfJavascript 对象从自身调用函数
【发布时间】:2013-05-26 07:59:10
【问题描述】:

我一直在阅读使用 HTML5 和 JavaScript 进行游戏设计,它向我介绍了对象。因此,在阅读了这本书并参与了项目之后,我决定利用这些新发现的知识并将对象集成到我自己的项目中。所以这是我的问题,对象可以或应该调用自己的函数吗?例如:

var someObject = {
    start: function() {
        check();
    },
    check: function() {
        console.log("Check!");
    }
};

someObject.start();

这本书确实展示了一个带有计时器的示例:

var timer = {
    start: function() {
        var self = this;
        window.setInterval(function(){self.tick();}, 1000);
    },
    tick: function() {
        console.log('tick!');
    }
};

在带有计时器对象的示例中,它引用 self 以调用内部函数,这是否意味着我应该使用 self 来调用内部函数,或者这是对对象执行此操作的正确方法?还是最佳实践?提前致谢。

var someObject = {
    start: function() {
        var self = this;
        self.check();
    },
    check: function() {
        console.log("Check!");
    }
};

someObject.start();

【问题讨论】:

  • 之所以在setTimeout的例子中使用它,是因为它的回调是在全局范围内执行的,所以setTimeout回调中this的值为window。为了保持对原始对象的引用,您必须使用该方法(将其存储在self)或某种形式的使用Function.bind()

标签: javascript function object prototype


【解决方案1】:

它是javascript函数上下文,每次创建函数时,都会创建一个新的上下文(作用域)。

setInterval() 函数中,您创建了一个新范围,因此this 不再指代相同的this

var self = this;
setInterval(function() {
    self.tick();
}, 1000);

您还可以使用bind() 手动绑定函数的正确上下文(因此您不再需要self):

setInterval(function() {
    this.tick();
}.bind(this), 1000);

更多信息:

【讨论】:

    【解决方案2】:

    JavaScript 名称为 lexically scoped,因此每当在脚本中遇到名称(变量)时,JavaScript 运行时必须搜索定义函数的作用域。

    在定义点,这个函数:

    start: function() {
        check();
    }
    

    在其外部范围内无权访问任何check 函数。声明self 并将其绑定到this 是一种用于处理(有些有趣的)intricacies of referring to the current object in JavaScript 的技术(因为示例代码使用window.setInterval)。

    要在当前对象中引用一个函数,使用this就足够了。

    var someObject = {
        start: function() {
            this.check();
        },
        check: function() {
            console.log("Check!");
        }
    };
    

    【讨论】:

      【解决方案3】:

      声明和初始化像“self”这样的变量的目的是处理this的值在每次函数调用时重新确定的事实。当您将一个函数嵌套在另一个函数中时,并且该内部函数需要从外部上下文访问 this 的值,则必须将 this 保留在另一个变量中 - 在您的情况下为“self”。 (该变量的名称当然不重要。)

      在您的示例代码中:

      var timer = {
          start: function() {
              var self = this;
              window.setInterval(function(){self.tick();}, 1000);
          },
          tick: function() {
              console.log('tick!');
          }
      };
      

      传递给setInterval() 的函数需要使用“start”函数中this 的值。但是,当调用该间隔计时器函数时,this 被设置为其他值(全局上下文或“严格”模式下的null)。因此,通过将this 的值保存在实例化该间隔计时器函数的上下文中,其代码可以使用它来访问计时器对象。

      在你的第二个例子中,声明和初始化一个“self”变量并没有什么坏处,但它是不必要的。然而,有时它很方便,只是为了澄清代码,当然比“self”更有意义的名称是个好主意。

      【讨论】:

      • 这不是第二个示例中所做的事情
      【解决方案4】:

      当然,一个对象可以并且应该调用它自己的函数,这是在 javascript 中模拟 OOP 的唯一方法。我会说这本书使用的做法,self = this 很糟糕,因为this 只能单独使用,但是在第一个示例中,它用于保留 this 的值,否则它将是 this函数本身而不是外部类

      【讨论】:

      • "模仿";只是不断告诉自己,也许你说的时候并拢脚跟......
      • var self = this的原因有很多;一个完全不相关的原因是让脚本压缩更有效。
      • @voithos 阅读了整个答案,我只说第二次使用不好
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-17
      相关资源
      最近更新 更多