2

我一直在尝试了解 Javascript 的功能组合技术,我想出了他的玩具准 MVC 工作代码来演示我的问题:

var modelFactory = function() {
  var _state = false;
  var _listener = null;

  var _updateView = function() {
    _listener(_state);
  };

  var _interface = {
    registerListener: function(listen) {
      _listener = listen;
    },
    eventHandler: function() {
      _state = true;
      _updateView();
    }
  };
  return _interface;
};

var viewFactory = function(updateFunction) {
  var _hook = $('<div class="box"></div>');
  $('body').append(_hook);

  var _interface = {
    getHook: function getHook() {
      return _hook;
    },
    update: updateFunction(_hook)
  };

  return _interface;
};


var main = function() {

  var modelInstance = modelFactory();

  var viewInstance = viewFactory(
    function bindHook (hook) {
      return function bindState (state) {
        if (state === true) {
          hook.addClass("red");
        } else {
          hook.removeClass("red");
        }
      };
    }
  );

  modelInstance.registerListener(viewInstance.update);
  modelInstance.eventHandler(); // When called, mutates _state, then calls the listener
};

$(document).ready(main);
.box {
  background-color: #000;
  width: 100px;
  height: 100px;
}
.red {
  background-color: #f00;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

在这段代码中,我传入了一个绑定“钩子”变量并返回其作用域保留该绑定的函数的函数。这是我问题的症结所在。

我希望能够抽象出“钩子”绑定,所以我可以将“状态”绑定函数传递给一个函数,然后执行“钩子”绑定。我还没有弄清楚如何使用 Javascript 提供的后期绑定工具来做到这一点(应用/调用它)。我可以传递对象引用以保持状态并完成工作,但我对解决此问题的更多功能方法感兴趣。所以:

a)有没有办法做我正在尝试用Javascript中的基本闭包做的事情,如果是这样的话,或者

b)如果我应该使用基于“this”的后期绑定方法,那么最好的方法是什么?我假设这是在 Javascript 中泛化函数状态的行之有效的方法,但我为此编写的代码最终毫无用处。

4

1 回答 1

0

我认为您只想将闭包的创建放在您的viewFactory

function viewFactory(updateFunction) {
  var _hook = $('<div class="box"></div>');
  return {
    getHook: function getHook() {
      return _hook;
    },
    update: function(state) {
      return updateFunction(_hook, state)
    }
  };
}

…
var viewInstance = viewFactory(function bindState(hook, state) {
  hook[state ? "addClass" : "removeClass"]("red");
});
$('body').append(viewInstance.getHook());
modelInstance.registerListener(viewInstance.update);

创建这个闭包只是部分应用的一个例子,它当然可以在一个辅助函数中抽象出来(被称为 like update: partial(updateFunction, _hook))。

您也可以将其用作函数绑定的bind一种部分应用程序。this假设你想将钩子传递为this,你要么写

update: function(state) {
  return updateFunction.call(_hook, state); // notice the similarity to above
}

或只是(等效地)

update: updateFunction.bind(_hook)
于 2015-01-21T03:43:28.220 回答