简体   繁体   English

为什么闭包比JavaScript中的全局变量安全?

[英]Why are closures safer than global variables in JavaScript?

I'm pretty new to programming and yet can't understand some basic concepts. 我对编程非常陌生,但无法理解一些基本概念。

I was reading this article http://www.w3schools.com/js/js_function_closures.asp (I got redirected there from another w3schools page telling me to 'avoid global variables'). 我正在阅读本文http://www.w3schools.com/js/js_function_closures.asp (我从另一个w3schools页面重定向到那里,告诉我“避免全局变量”)。

However, I can't really understand how do closures "beat" the globals. 但是,我无法真正理解闭包如何“击败”全局变量。

From what I have seen and read, global variables are dangerous, because any script or user can modify them what could possibly ruin the code functionality. 从我所看到和阅读的内容来看,全局变量很危险,因为任何脚本或用户都可以修改它们,这可能会破坏代码功能。

Anyway- if we consider code from the link: 无论如何-如果我们考虑链接中的代码:

var add = (function () {
var counter = 0;
return function () {return counter += 1;}
})();

And if we consider global variable: 如果我们考虑全局变量:

var counter = 0;
function add(){
counter = counter+1;
return counter;
}

How is the first case less accessible by script than second? 与脚本的第二种情况相比,脚本如何无法访问第一种情况? Doesn't it take in both cases one line of code to change the variable? 两种情况下都不需要一行代码来更改变量吗? The only thing that came on my mind is declaring closure in another function where it gets executed, so it becomes accessible only locally: 我唯一想到的就是在另一个执行该函数的地方声明闭包,因此只能在本地访问:

function exec(){

var add = (function () {
var counter = 0;
return function () {return counter += 1;}
})();

console.log(add());
}

But I don't think this would do the job. 但是我认为这不会做。

In the first case, code outside the add function cannot touch the counter. 在第一种情况下, add功能之外的代码无法触摸计数器。 They could separately create a counter variable, but it would be a different variable from the counter used by add , and wouldn't affect the operation of add . 他们可以分别创建一个counter变量,但这将是与add使用的计数器不同的变量,并且不会影响add的操作。

In the second case, any code that touched the global counter would be able to affect add 's operation. 在第二种情况下,任何触及全局counter代码都将能够影响add的操作。

The thing you might be missing is that the first add function is immediately executed. 您可能缺少的是,第一个添加函数将立即执行。 This is indicated by the parenthesis which follow its declaration. 这由声明后的括号表示。 eg: 例如:

var something = function(){}();

Because this immediate execution returns a function, the add variable now represents that returned function with the counter variable set to 0 (which was also included in the immediately executed function). 因为此立即执行将返回一个函数,所以add变量现在将计数器变量设置为0(也包含在立即执行的函数中)表示该返回的函数。

Because it was declared within a function, that counter variable is now only visible to that function, and thus is protected from being overwritten by any other counter variable declared later in the program. 因为它是在函数中声明的,所以该计数器变量现在仅对该函数可见,因此可以防止被稍后在程序中声明的任何其他计数器变量覆盖。

The calls to add now run that interior function, using the counter variable that was declared within add, and can now no longer be manipulated by anything but that interior function. 现在,对add的调用使用在add中声明的计数器变量运行该内部函数,并且除该内部函数外,现在不再可以对其进行任何操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM