Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/powerbi/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
学习javascript中的闭包及其工作原理_Javascript_Closures - Fatal编程技术网

学习javascript中的闭包及其工作原理

学习javascript中的闭包及其工作原理,javascript,closures,Javascript,Closures,我试图学习JavaScript中的闭包 let f, g; function foo() { let x; f = function() { return ++x; }; g = function() { return --x; }; x = 1; console.log('inside foo, call to f(): ' + f()); } foo(); console.log('call to g(): ' + g()); console.l

我试图学习JavaScript中的闭包

let f, g;
function foo() {
  let x;
  f = function() {
    return ++x; };

  g = function() {
    return --x; };

  x = 1;
  console.log('inside foo, call to f(): ' + f());

}
foo();  
console.log('call to g(): ' + g());
console.log('call to f(): ' + f());
我得到:

inside foo, call to f(): 2
call to g(): 1
call to f(): 2

现在最让我困惑的是,为什么f()在函数外部仍然是2。你就是这么做的吗?有人能用最简单的方式解释一下吗。谢谢

我想你对“为什么我在外部范围内声明f可以访问x”感到困惑。这是因为JavaScript首先在foo内部启动一个匿名函数,x对该函数是可见的。然后你把它赋给全局变量f,这样它就包含了foo的作用域。

我想你对“为什么f可以访问x,即使我在外部作用域声明了它”感到困惑。这是因为JavaScript首先在foo内部启动一个匿名函数,x对该函数是可见的。然后将其分配给全局变量f,这样它就包含了foo的作用域。

这实际上不是闭包。您需要将所有内容包装起来,只公开您想要公开的属性,这些属性可以保留对非公开部分的访问


搜索javascript模式。。。有一些关于模块、单例等的很好的参考,这并不是一个闭包,真的。您需要将所有内容包装起来,只公开您想要公开的属性,这些属性可以保留对非公开部分的访问

foo();  //2
foo();  //2
foo();  //2
搜索javascript模式。。。对模块、单例等有一些很好的参考

foo();  //2
foo();  //2
foo();  //2
如果只调用第一次
foo()然后输出将在foo内部,调用f():2

第二次
foo()然后输出将在foo内部,调用
f():2

因为每个函数都在内存中声明然后使用

但是当你使用as
f()使用
foo()后

因为您使用了as闭包函数
f()功能

如果只调用第一次
foo()然后输出将在foo内部,调用f():2

第二次
foo()然后输出将在foo内部,调用
f():2

因为每个函数都在内存中声明然后使用

但是当你使用as
f()使用
foo()后


因为您使用了as闭包函数
f()功能当然,您可以使用全局变量来保存总数。但是请记住,如果你使用globals,这个家伙会把你活活吃掉

对于这样的场景,闭包是在不使用全局变量的情况下维护函数调用之间状态的最佳候选者。让我们看看如何

(函数(){
函数addFn(arg){
var合计=0;
var mul=arg;
如果(总数>5){
返回函数(val){
总+=val;
log(“hello:+total”);
返回总数+9;
}
}否则{
log(“嘿:”+mul);
返回函数(arg1){
mul=mul*arg1;
console.log(“乘法:+mul”);
返回mul;
};
}
};
var mulcc=addFn(7);
控制台日志(mulcc);
mulcc(2);//14
mulcc(5);//70
mulcc(1);//70

}());当然,您可以使用全局变量来保存总数。但是请记住,如果你使用globals,这个家伙会把你活活吃掉

对于这样的场景,闭包是在不使用全局变量的情况下维护函数调用之间状态的最佳候选者。让我们看看如何

(函数(){
函数addFn(arg){
var合计=0;
var mul=arg;
如果(总数>5){
返回函数(val){
总+=val;
log(“hello:+total”);
返回总数+9;
}
}否则{
log(“嘿:”+mul);
返回函数(arg1){
mul=mul*arg1;
console.log(“乘法:+mul”);
返回mul;
};
}
};
var mulcc=addFn(7);
控制台日志(mulcc);
mulcc(2);//14
mulcc(5);//70
mulcc(1);//70

}());为什么会让你困惑?你期望的价值是什么?为什么会让你困惑?您期望哪个值?
f
g
访问在它们之外定义的变量。这些怎么不是闭包呢?它们都是在函数foo的范围内定义的。因为它们位于该函数的顶层(范围),所以与它们一起定义的任何其他函数都可以访问它们。如果您在这些函数中的每个函数中定义了变量,它们将位于这些闭包中,并且在其他任何地方都不可用。
f
g
访问在它们之外定义的变量。这些怎么不是闭包呢?它们都是在函数foo的范围内定义的。因为它们位于该函数的顶层(范围),所以与它们一起定义的任何其他函数都可以访问它们。如果在这些函数中的每个函数中定义了变量,那么这些变量将位于这些闭包中,并且在其他任何地方都不可用。f()在函数外部仍然不是2,它是递增的。f()在函数外部仍然不是2,它是递增的。