在函数中获取正确的范围(不使用that = this)

时间:2015-03-27 13:38:39

标签: javascript angularjs

我正在尝试修复我在这里使用它的功能,而不使用那个=这个(或者自我=这就像使用一样)。这是一个范围问题,但我不知道如何解决它,我想养成不使用那个=这个的习惯。所以函数都在返回(角度工厂),我无法引用另一个函数。让我告诉你我的意思:

  return {
            loadStates: function() {

                     var that = this;
                     //chgeck if is loaded module, then change and fire callback
                     var currentModules = moduleHolder.getModules();
                     if (currentModules[name]) {
                        //works here
                         this.prepState();

                     } else {
                         //module cannot be found check for 5 seconds
                         $log.warn("Requesting " + name + "...");
                         var timeToCheck = true;
                         setTimeout(function() {
                             timeToCheck = false;
                         }, 5000);
                         var check = {
                             init: function() {
                                 check.checkAgain();
                             },
                             checkAgain: function() {
                                 if (timeToCheck) {
                                     if (currentModules[name]) {
                                        //but not here
                                         that.prepState();
                                     } else {
                                         //still doesn't exists
                                         setTimeout(check.checkAgain, 200);
                                     }
                                 } else {
                                     //doesn't exist after 5 seconds
                                     $log.error("Requested module (" + name + ") could not be found at this time.");
                                 }
                             }
                         };
                         check.init();
                     }

                 },
                 prepState: function() {

                 }

             }

所以在顶部如果找到currentModule [name]我可以使用this.prepState()并且它工作正常。但是在计时功能中我不能使用这个任何东西,因为它在不同的范围内,所以我暂时通过设置一个=这个顶部来解决这个问题,但是我想看看我是否不能使用这个方法。如何在不使用那个=这个的情况下解决这个问题?谢谢!

3 个答案:

答案 0 :(得分:2)

  

这是一个范围问题......

不,不是。 this和范围基本上没有任何关系。 (目前为止; ES6的箭头功能会改变它。)这是如何调用函数的问题。

如果你将一个函数引用传递给稍后会调用它的东西,除非你传递给它的东西有一种方法可以用来告诉它在调用时this使用什么,您的函数将被this调用,而不是指您想要引用的内容。

您可以使用this获取一个新功能参考,该参考将使用正确的Function#bind调用原始函数:

var usesCorrectThis = originalFunction.bind(valueForThis);

例如,假设我有:

var check = {
    name: "Fred",
    sayHello: function() {
        console.log("Hi, I'm " + this.name);
    }
};

如果我这样做:

check.sayHello();

一切都很好:调用函数作为从属性中检索它的表达式的一部分,告诉JavaScript引擎在调用期间将对象用作this

但是,如果我这样做:

setTimeout(check.sayHello, 0);

...这样做不对,因为当setTimeout调用该函数时,它并没有使用this的正确值。

所以我可以使用Function#bind来解决这个问题:

setTimeout(check.sayHello.bind(check), 0);

更多(在我的博客上)

答案 1 :(得分:0)

有不同的方法可以做到这一点。 一种方法是使用bind函数。你可以使用

 var checkInitBindFn = check.init.bind(this);
 checkInitBindFn();

其次,你也可以使用电话和申请。

check.init.call(this);
check.init.apply(this);

像这样你可以用它而不是那个。 在线查看完整的api doc ...

答案 2 :(得分:0)

这不是一个范围问题。如果要避免self = this,则始终可以按对象引用函数。制作更干净的代码,因为有角度的工厂是单身,你不会浪费记忆。

angular.module('myApp').factory('myFactory', function ($timeout) {

  var myFactory = {
    loadState: function () {

      $timeout(function () {
        myFactory.check();
      }, 500);

    },
    check: function () {

    },
  };

  return myFactory;

});