Javascript闭包定义说:
“闭包”是一个可以免费的表达式(通常是一个函数) 变量以及绑定这些变量的环境 (“关闭”表达式)。
有人可以向我解释自由变量的概念吗?这个概念是Javascript特定的还是适用于其他语言?
答案 0 :(得分:27)
自由变量只是既未在本地声明也未作为参数传递的变量。
在计算机编程中,术语自由变量是指变量 在函数中使用,不是局部变量,也不是参数 function。1术语非局部变量通常是其中的同义词 上下文。
在javascript闭包中,这些只是函数在声明闭包或在父作用域中的封闭作用域中获取(读取和写入)的变量。
看看这个真实世界的例子:
Gol.prototype._ensureInit = function() {
...
var _this = this;
var setDim = function() {
_this.w = _this.canvas.clientWidth;
_this.h = _this.canvas.clientHeight;
_this.canvas.width = _this.w;
_this.canvas.height = _this.h;
_this.dimChanged = true;
_this.draw();
};
setDim();
window.addEventListener('resize', setDim);
...
};
在此示例中,闭包从setDim
函数指向封闭范围(_this
函数)中声明的变量_ensureInit
。此变量未在setDim
中声明,也未传递。这是“自由变量”。
请注意,_this
不会成为函数setDim
的变量:在同一范围内声明的另一个函数将共享同一个变量。
答案 1 :(得分:2)
“免费翻译”可以是:"out of scope" - variables
。
由于ECMAscript使用词法作用域,因此自由变量是在父作用域中定义的变量,并通过作用域链搜索进行查找。
(function _outerScope() {
var foo = 42;
(function _innerScope() {
var bar = 100;
console.log( foo + bar ); // 142
}());
}());
在上面的示例中,foo
是_innerScope
上下文中的自由变量。如果我们快速浏览一下ECMAscript的基本概念,就会变得非常明显。
上下文链接到激活对象(在ES3中),分别是 Lexical Enviroment Record (在ES5中),其中包含的东西例如:function declarations
,variables declared with var
和formal paramters
,以及对所有父激活对象 / Lexical Environments 的引用。如果需要访问变量,ECMAscript引擎将首先从当前 Context 本身查看 AOs / LEs ;如果在那里找不到,它会查看父 AO 的/ LE 。
由于任何 Context 将此数据存储在类似数组的结构中(不要忘记我们在这里讨论的是实现级别,而不是Javascript本身),我们是谈论Lexical Scope
,因为我们按顺序搜索所有父上下文。
答案 2 :(得分:0)
举个例子:
var myModule = (function (){
var moduleVar; // closure variable
return function(){
// actual function
}
})();
定义的变量有一个闭包变量。它可以在闭包本身使用,但不是全局命名空间的一部分。
答案 3 :(得分:0)
我不记得我读了多少 JS 书籍并修改了一些有闭包主题的主题。
答案只是对已接受答案的补充。
以下示例摘自Modern JavaScript for the Impatient, Cay Horstmann
// text is a free variable of the arrow function.
const sayLater = (text, when) => {
// vv
let task = () => console.log(text) // (heed no 'text' variable here) => console.log(text)
setTimeout(task, when)
}
现在你可以理解
的意思了 <块引用>术语自由变量是指在函数中使用的变量 不是该函数的局部变量或参数。