【问题标题】:Add additional parameters to event function向事件函数添加附加参数
【发布时间】:2016-09-06 17:17:52
【问题描述】:

我有一个事件,我想为命名函数添加额外的参数。我尝试了以下两件事:

myDiv.addEventListener('click', evt.call(this, event, 'hello'));

myDiv.addEventListener('click', evt(event, 'hello'));

他们两个的问题是,他们会立即被调用,而不是当你点击 myDiv 时被调用,即当它应该被调用时。

如何向命名函数事件添加其他参数?

JSFiddle

console.clear();

var myDiv = document.getElementById('myDiv');

function evt(event, param1) {
  console.log(event + ' and ' + param1)
}

myDiv.addEventListener('click', evt.call(this, event, 'hello'));
#myDiv {
  width: 200px;
  height: 200px;
  background-color: green;
}
<div id="myDiv"></div>

【问题讨论】:

  • 您在寻找bind吗?
  • 了解Function#bind
  • @MikeC 不,我不想改变this。我只是想给事件函数添加更多参数
  • @MikeC 你是对的!我以为bind 只是添加this。谢谢!在性能方面,使用匿名包装器然后使用 return evt.call(this, event, 'hello'); 或使用 bind 创建变量之间哪个更好?
  • @Jessica 你必须确认一下,但我的假设是匿名函数更快,因为它不必绑定this。这仅取决于您是否需要 this 等于某个值,以及这是否是代码的性能关键部分。

标签: javascript dom-events


【解决方案1】:

您可以使用匿名包装器:

myDiv.addEventListener('click', function(event) {
    return evt.call(this, event, 'hello');
});

或者,你可以给自己一个实用函数(我倾向于称它为curry;纯粹主义者可能会反对这个名字)。这是一个未优化的现成代码:

Object.defineProperty(Function.prototype, "curry", {
    value: function() {
        var f = this;
        var boundArgs = Array.prototype.slice.call(arguments);
        return function() {
            return f.apply(this, boundArgs.concat(Array.prototype.slice.call(arguments)));
        };
    }
});

然后:

myDiv.addEventListener('click', evt.curry('hello'));

但是您必须为此更改evt 中的参数顺序:

function evt(param1, event) {
  console.log(event + ' and ' + param1)
}

...因为我的curry 版本首先将柯里化参数传递给它,然后是调用柯里化版本的参数。虽然我想如果你愿意的话,交换它们很容易。

这是 ES2015+ 中的 curry 函数:

Object.defineProperty(Function.prototype, "curry", {
    value(...boundArgs) {
        var f = this;
        return function(...callArgs) {
            return f.call(this, ...boundArgs, ...callArgs);
        };
    }
});

【讨论】:

  • 谢谢!在性能方面,使用匿名包装器然后 return evt.call(this, event, 'hello'); 或使用 bind 创建变量之间哪个更好?
  • 这是一个元评论,但是:有大量的重复,但它们大多隐藏在糟糕/不相关的标题和措辞后面。通常提问者甚至不知道他们的实际问题是什么。 Jessica 的帖子标题不错,也许这篇帖子是潜在的规范复制目标?
  • @Teemu:这正是我在查找时发现的完全,实际问题隐藏在onxyz 属性或jQuery 或其他非常糟糕的代码中。杰西卡是一个很好的,清晰的,简单的。我在,我将保存此链接并在将来使用它。我已经将答案设置为 CW(只是让我对指向未来的人感觉更好)。
  • @Jessica:真的,真的不太可能有什么表现更好。如果我不得不猜测(这将是一个猜测),我会说可能是匿名函数。但是那里有很多副作用,例如因为它是一个闭包,所以当你创建它时它会关闭范围内的所有内容。现代引擎现在非常擅长优化,但仍然......也就是说,如果你保持你的函数很小并且避免深度嵌套,我怀疑它是否重要。
  • @T.J.Crowder 谢谢!
【解决方案2】:

只需为您的事件处理程序使用一个匿名函数,该函数调用您的 evt 函数并传入事件对象和一个参数:

myDiv.addEventListener('click', function ( e ) {
  evt( e, 'hello' );
} );

【讨论】:

  • this-context 会坚持下去吗?
  • 不是上面那个,没有。
  • @Rayon 否,但this 未在evt 中使用。如果是,您可以使用evt.call( this, e, 'hello' );
猜你喜欢
  • 1970-01-01
  • 2021-11-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多