JavaScript中的闭包

大多数JavaScript开发人员使用 关闭 有意无意地。即使他们无意识地这么做了,在大多数情况下效果也很好。但是知道闭包可以在使用它们时更好地控制代码。学习闭包的另一个原因是,它是JavaScript开发人员面试中最常问的问题。 先决条件: : JavaScript中的变量作用域

null

让我们通过一个例子来了解闭包。

例1:

Javascript

// Explanation of closure
/* 1 */ function foo()
/* 2 */ {
/* 3 */ var b = 1;
/* 4 */ function inner(){
/* 5 */ return b;
/* 6 */ }
/* 7 */ return inner;
/* 8 */ }
/* 9 */ var get_func_inner = foo();
/* 10 */ console.log(get_func_inner());
/* 11 */ console.log(get_func_inner());
/* 12 */ console.log(get_func_inner());


说明: 值得注意的是 9号线 12号线 .在第9行,我们完成了 函数foo() 以及整个 函数内部() 返回并存储在 var get_func_inner ,由于7号线 返回内部 . [return语句不执行内部函数–函数仅在后跟()时执行,而是返回对函数的引用,因为JavaScript中的函数也是一个对象。]

我们可以访问变量 B 定义如下: 函数foo() 通过 函数内部() 因为后者在执行封闭函数时保留了封闭函数的作用域链,即内部函数知道 B 通过它的范围链。 这就是闭包,即内部函数可以访问外部函数变量以及所有全局变量。 上述代码的输出:

Output_example_1

为了查看闭包中的变量和函数边界,我们可以这样写:

Javascript

/* 13 */ console.dir(get_func_inner);


输出:

Output_dir_for_function

正如我们可以在范围部分中看到闭包中的变量一样。

关闭的定义:

在编程语言中,闭包(也称为词汇闭包或函数闭包)是在具有一级函数的语言中实现词汇范围的名称绑定的技术。从操作上讲,闭包是一个存储函数[a]和环境[1]的记录,它是一个映射,将函数的每个自由变量(在本地使用但在封闭范围内定义的变量)与创建闭包时名称所绑定的值或引用相关联。[b] -维基百科

换句话说,当子函数即使在父函数已经执行之后仍保留父作用域的环境时,就会创建闭包

现在让我们来看另一个例子。

例2:

Javascript

function foo(outer_arg) {
function inner(inner_arg) {
return outer_arg + inner_arg;
}
return inner;
}
var get_func_inner = foo(5);
console.log(get_func_inner(4));
console.log(get_func_inner(3));


说明: 在上面的示例中,我们使用了参数函数,而不是默认函数。注意,即使我们已经完成了 傅(5) 我们可以进入 外_arg 来自内部函数的变量。在执行内部函数时,产生 外_arg 内_arg 如你所愿。

输出:

Ouput_example2

现在我们来看一个循环中的闭包示例。 在本例中,我们希望在数组的每个索引处存储一个匿名函数。

例3:

Javascript

// Outer function
function outer()
{
var arr = [];
var i;
for (i = 0; i < 4; i++)
{
// storing anonymous function
arr[i] = function () { return i; }
}
// returning the array.
return arr;
}
var get_arr = outer();
console.log(get_arr[0]());
console.log(get_arr[1]());
console.log(get_arr[2]());
console.log(get_arr[3]());


输出:

Ouput_example_3

说明: 你猜对答案了吗?在上面的代码中,我们创建了四个闭包,指向变量i,它是函数outer的局部变量。 我不记得它的价值 这个变量只有 要点 到变量或存储 参考 并因此返回当前值。在上面的代码中,当我们试图更新它的值时,它会反映给所有人,因为闭包存储了引用。

让我们看看编写上述代码的正确方法,以便在不同索引处获得不同的i值。

例4:

Javascript

// Outer function
function outer()
{
function create_Closure(val)
{
return function ()
{
return val;
}
}
var arr = [];
var i;
for (i = 0; i < 4; i++)
{
arr[i] = create_Closure(i);
}
return arr;
}
var get_arr = outer();
console.log(get_arr[0]());
console.log(get_arr[1]());
console.log(get_arr[2]());
console.log(get_arr[3]());


输出:

Ouput_example3_modified

说明: 在上面的代码中,我们在每次调用时更新函数create_Closure的参数。因此,我们在不同的指数下得到不同的i值。

注: 一下子理解闭包的概念可能有点困难,但是试着在不同的场景中尝试闭包,比如创建getter/setter、回调等等。

参考: 斯托扬·斯特凡诺夫的《面向对象的JavaScript》 本文由 苏米特·戈什 .如果你喜欢GeekSforgek,并想贡献自己的力量,你也可以使用 写极客。组织 或者把你的文章寄到contribute@geeksforgeeks.org.看到你的文章出现在Geeksforgeks主页上,并帮助其他极客。 如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写下评论。

© 版权声明
THE END
喜欢就支持一下吧
点赞13 分享