JavaScript代理模式解释

时间:2012-09-13 18:21:33

标签: javascript web-applications javascript-events proxy-pattern

我研究JavaScript代理模式,但我仍然没有,我可以从中受益。因此,我想向您提供两个例子,请您指出它们之间的区别。

请看下面的代码:

  • 两个addEventListener来电有什么区别?其中一个以常规方式调用handleDrop。另一个使用代理模式。
  • 使用代理模式方法可以获得什么?

我测试了两个功能,他们都成功调用了handleDrop

DndUpload.prototype.buildDropZone = function ()
{
    var self = this,

    this.dropZone.addEventListener('drop', function (e) { self.handleDrop.call(self, e) }, false);
    this.dropZone.addEventListener('drop', self.handleDrop, false);


    DndUpload.prototype.handleDrop = function (e)
    {
        alert("test");
        ...
    };
}

您可以为我提供很好的参考资料,其中包含JavaScript中代理模式的非常清晰的解释。

提前致谢。

2 个答案:

答案 0 :(得分:3)

基本上,直接传递self.handleDrop在功能上等同于传递以下函数:

function() {
  return self.handleDrop.apply(this, arguments);
}

因为所有内容都传递给原始函数:

  • this
  • 参数
  • 返回值

考虑到这一点,请按照以下方式比较您的功能:

function(e) { self.handleDrop.call(self, e) }
function() { return self.handleDrop.apply(this, arguments); }

与代理方式的区别在于:

  • 它没有通过返回值。
  • 它不会传递所有参数(仅限第一个e
  • 它未通过this值,但使用预定义值:self

现在,前两个项目在这里没有区别,因为addEventListener并不关心返回值,而且它也只传递一个参数。

但第三项很重要:它在函数中设置了不同的this值。默认情况下,this是将事件绑定到的元素(由浏览器设置)。使用代理方式,您可以设置另一个this值。

现在,在您的代码段中,每次调用buildDropZone时,为什么要设置原型函数并不完全清楚。通常只定义一次原型函数。但是当使用代理方式调用处理程序handleDrop时,this引用DndUpload实例,这与一般的原型函数一致。

答案 1 :(得分:2)

请考虑以下代码:

function printThis() {
  console.log(this);
}

var someObject = {
  performTest : function() {
    var self = this;

    someOtherObject.higherOrderFunction(printThis);
    someOtherObject.higherOrderFunction(function(){printThis.call(self)});
  }
}

var someOtherObject = {
  higherOrderFunction : function(f) {
      f();
  }
}

someOtherObject.higherOrderFunction(printThis)将返回什么? someOtherObject.higherOrderFunction(function(){printThis.call(self)})

怎么样?

第一个问题的答案取决于你调用someObject.performTest()的方式和方式。如果我只是从全局上下文中调用someObject.performTest(),它可能会打印Window

第二个将始终打印someObject实例,无论如何。

当您想要精确控制函数的执行上下文时,您调用它时的闭包或“代理模式”会派上用场。

注意:javascript中的this行为与其他语言中的行为不同(例如在Java中)。