在 Javascript 中,闭包可以与函数 return 值共享作用域吗?
In Javascript, can a closure share scope with a function return value?
我试图从 Eloquent Javascript 中理解这个无法解释的代码:
function trackKeys(keys) {
let down = Object.create(null);
function track(event) {
if (keys.includes(event.key)) {
down[event.key] = event.type == "keydown";
event.preventDefault();
}
}
window.addEventListener("keydown", track);
window.addEventListener("keyup", track);
return down;
}
var arrowKeys =
trackKeys(["ArrowLeft", "ArrowRight", "ArrowUp"]);
我想我明白内部函数 track
将如何维护对 down
和 keys
的引用,因为它是一个闭包,但我迷失在 return down;
return 值会是对回调正在访问的 down
完全相同的引用吗?我不明白;我以为局部变量只能被内部函数访问?
跟进:如果 down 是原始数据类型而不是对象,这仍然有效吗?
该函数将变量 down
初始化为一个对象。
所以在函数内部,down
是一个指向某个对象的变量
当函数 returns down
时,它 returns 是对象的引用,这意味着对象可以通过函数的 return 访问。
如果 down
是原始值,那么这将不起作用,因为该函数只会 return 原始值而不是对对象的引用。
TLDR: 由于人类语言固有的不精确性,说“一个变量是 returned”是模棱两可的。这并不意味着标识符和值的变量对是 returned。这意味着变量的 value 是 returned。在这种情况下,对对象(由 Object.create(null)
创建)的引用的值是 returned.
Will that return value be a reference to the exact same down
the
callbacks are accessing?
是的。
I thought local variables could only be accessed by inner functions?
变量是标识符(即变量的名称)和值的配对。
范围是标识符(在本例中为“down
”)具有特定含义的代码区域。
标识符的范围由声明变量的方式决定(const
/let
/var
/在非严格模式下是隐式的)。使用 let
声明变量 down
;因此它的作用域是最近的包含块,即函数 trackKeys
.
在 trackKeys
内声明的函数将通过 JavaScript 的内置闭包形成机制关闭 down
,因此将共享标识符“向下”的含义。
注意:如果内部函数或块 也 声明它们自己的名为 "down"
的变量,这些内部变量将导致错误(var
在严格模式下的非功能块,重复声明),什么也不做(var
在非功能块的非严格模式下),或隐藏(从视图中隐藏)外部变量(let
/ const
).
返回 down
不会更改标识符 down
的范围。尝试在 trackKeys
之外引用“向下”将继续出错或 return 未定义,具体取决于您是否处于严格模式。然而,返回 down
的值确实使该值在 trackKeys
.
之外可用
我试图从 Eloquent Javascript 中理解这个无法解释的代码:
function trackKeys(keys) {
let down = Object.create(null);
function track(event) {
if (keys.includes(event.key)) {
down[event.key] = event.type == "keydown";
event.preventDefault();
}
}
window.addEventListener("keydown", track);
window.addEventListener("keyup", track);
return down;
}
var arrowKeys =
trackKeys(["ArrowLeft", "ArrowRight", "ArrowUp"]);
我想我明白内部函数 track
将如何维护对 down
和 keys
的引用,因为它是一个闭包,但我迷失在 return down;
return 值会是对回调正在访问的 down
完全相同的引用吗?我不明白;我以为局部变量只能被内部函数访问?
跟进:如果 down 是原始数据类型而不是对象,这仍然有效吗?
该函数将变量 down
初始化为一个对象。
所以在函数内部,down
是一个指向某个对象的变量
当函数 returns down
时,它 returns 是对象的引用,这意味着对象可以通过函数的 return 访问。
如果 down
是原始值,那么这将不起作用,因为该函数只会 return 原始值而不是对对象的引用。
TLDR: 由于人类语言固有的不精确性,说“一个变量是 returned”是模棱两可的。这并不意味着标识符和值的变量对是 returned。这意味着变量的 value 是 returned。在这种情况下,对对象(由 Object.create(null)
创建)的引用的值是 returned.
Will that return value be a reference to the exact same
down
the callbacks are accessing?
是的。
I thought local variables could only be accessed by inner functions?
变量是标识符(即变量的名称)和值的配对。
范围是标识符(在本例中为“down
”)具有特定含义的代码区域。
标识符的范围由声明变量的方式决定(const
/let
/var
/在非严格模式下是隐式的)。使用 let
声明变量 down
;因此它的作用域是最近的包含块,即函数 trackKeys
.
在 trackKeys
内声明的函数将通过 JavaScript 的内置闭包形成机制关闭 down
,因此将共享标识符“向下”的含义。
注意:如果内部函数或块 也 声明它们自己的名为 "down"
的变量,这些内部变量将导致错误(var
在严格模式下的非功能块,重复声明),什么也不做(var
在非功能块的非严格模式下),或隐藏(从视图中隐藏)外部变量(let
/ const
).
返回 down
不会更改标识符 down
的范围。尝试在 trackKeys
之外引用“向下”将继续出错或 return 未定义,具体取决于您是否处于严格模式。然而,返回 down
的值确实使该值在 trackKeys
.