在方法addEventListener中,如何将参数x传递给实现console.log(x)的匿名函数来返回事件?
我不明白
console.log(x)
在下面的情况下是如何工作的。
我理解
addEventListener("keydown", function)
表示当按下 keydown 时,执行该函数(此处打印到控制台)。
但是,我真的无法理解当我们在方法 addEventListener() 中将参数传递给匿名函数(此处为
x
)时,事情是如何工作的,然后实现 console.log(x) 会将
keydown
事件打印到控制台。
document.addEventListener("keydown", function(x) {
console.log(x); // e.g. KeyboardEvent {isTrusted: true, key: "x", code: "KeyX", location: 0, ctrlKey: false, …}
});
与
(一个小提示是,使用
event
我可以直接使用
function()
,它仍然有效)相同:
document.addEventListener("keydown", function() { //here no need to input `event` as parameter
console.log(event); // e.g. KeyboardEvent {isTrusted: true, key: "x", code: "KeyX", location: 0, ctrlKey: false, …}
});
但是
document.addEventListener("keydown", function() { //no parameter
console.log(x); // Uncaught ReferenceError: x is not defined
});
触发事件时,调用的函数默认会获取传递给它的
Event
对象作为参数。在第一种情况下,由于函数的唯一参数是
x
,因此它会接收
Event
对象。实际上,这相当于这样写:
document.addEventListener("keydown", function() {
var x = event;
console.log(x);
});
在第二种情况下,您直接通过
event
变量访问
Event
对象(即不将其分配给另一个变量)。在第三种情况下,您尝试访问未定义的变量
x
,因此出现错误消息。
让我们用自己的逻辑复制这些场景,以更好地说明发生了什么。我将通过直接调用回调而不是等待事件来简化一些事情。这对您询问的事情没有任何影响。
设置
让我们考虑以下接受并调用回调的简单函数:
function fire(callback) {
callback(42);
}
如您所见,
fire
将参数传递给回调。
事件处理程序也会发生这种情况:当事件触发时,浏览器将调用事件处理程序并将当前事件对象传递给它。
第一种情况
如果函数定义了
参数
,它可以访问传递的参数。因此,如果我按如下方式调用
fire
:
fire(function(x) {
console.log(x);
});
然后我的回调接收并记录
42
。我可以为参数选择任何名称,它都会起作用。
这与您的第一个示例相同:您正在定义一个参数并决定将其命名为
x
。您可以给它起任何其他名字。
第二种情况
在此示例中,您正在访问变量
event
。由于变量未在函数内部定义并且不是参数,因此将在外部作用域中查找它(这基本上就是闭包的工作方式)。现在,碰巧
event
是一个
全局变量,它引用当前处理的事件
。
在我们的玩具示例中,它将如何工作?想象一下
fire
首先将值分配给全局变量:
var globalArg;
function fire(callback) {
globalArg = 42;
callback(globalArg);
}
您可以看到,该值可用作回调的参数以及全局变量
globalArg
。这就是为什么这两个示例都可以工作(对应于您的第一个和第二个场景):
fire(function(x) {
console.log(x);
});
fire(function() {
console.log(globalArg);
});
第三种情况
与第二种情况类似,
x
是一个既未在函数内部定义的变量,也不是参数。因此,在外部环境中查找该变量。但是,该变量也不存在,因此会引发错误。