Javascript范围和闭包使用详细的解决方案

动作范围的嵌套将形成动作链,函数的嵌套将形成闭包。闭包和范围链是Javascript的最重要的特性之一,与其他语言不同。

行动范围
Javascript中有两个作用域:函数作用域和全局作用域。

函数中声明的变量和函数的参数具有相同的作用域,即函数作用域:

复制代码代码如下所示:
函数(){
var bar = 1;
{
var bar = 2;
}
返回栏2;
}


C和其他块作用域等不同的语言总是返回到2。

浏览器的全球范围内,它可以被理解为一个窗口对象(Node.js是全球):
复制代码代码如下所示:
var bar = 1;
函数(富){ }
警报(窗口栏);1
警报(窗口)


变量条和函数符都属于全局作用域,所有这些都是窗口的属性。

作用域链
在Javascript中访问变量时,它从本地变量和参数开始,并将范围遍历到全局范围。

复制代码代码如下所示:
var范围= 0,零= 全局范围;
(函数(){())
VAR范围= 1,=一scope-1 ;
(函数(){())
VAR范围= 2,两=scope-2 ;
(函数(){())
VAR范围= 3,三=scope-3 ;
scope-2 scope-1全球范围 / / scope-3
console.log({三,二,一,零}。加入());
console.log(范围); / / 3
});
console.log(类型三); / /未定义
console.log(范围); / / 2
});
console.log(typeof两); / /未定义
console.log(范围); / / 1
});
console.log(类型一); / /未定义
console.log(范围); / / 0


在最内层的函数中,每一个变量都可以一步一步地遍历输出,在倒数第二层函数中,变量三不能被遍历,所以输出是不确定的。

举个通俗的例子。当你打算花钱买东西时,你首先会感觉到自己的钱包。如果你不这样做,你可以向你父亲寻求帮助,你父亲也不会再找到你的祖父,而当你的父亲没有钱买东西时,他就不会来找你。

关闭
在函数中,定义了另一个函数,称为函数嵌套。函数的嵌套将形成闭包。

闭包和作用链是相辅相成的,函数的嵌套创建一个闭包,同时产生多个链关系域。
复制代码代码如下所示:
函数绑定(函数,目标){
返回函数(){
func.apply(目标、参数);
};
}


那么你如何理解闭包呢

外部函数无法访问嵌入函数。
外部函数不能访问嵌入式函数的参数和变量。
嵌入式函数可以访问外部函数的参数和变量。
另一种说法是:内嵌函数包含外部函数的作用域。
让我们看一看前面描述的范围链的例子,这次从闭包的角度理解。

复制代码代码如下所示:
var范围= 0,零= 全局范围;
(函数(){())
VAR范围= 1,=一scope-1 ;
(函数(){())
VAR范围= 2,两=scope-2 ;
(函数(){())
VAR范围= 3,三=scope-3 ;
scope-2 scope-1全球范围 / / scope-3
console.log({三,二,一,零}。加入());
console.log(范围); / / 3
});
console.log(类型三); / /未定义
console.log(范围); / / 2
});
console.log(typeof两); / /未定义
console.log(范围); / / 1
});
console.log(类型一); / /未定义
console.log(范围); / / 0


最内层的函数可以访问所有定义在内部和外部的变量,倒数第二级函数不能访问最里面的变量。同时,范围= 3的最内层不会影响其外部同名变量。

然后改变角度来了解闭包。

每次调用外部函数时,都会创建一次嵌入函数。
当它被创建时,外部函数的范围,包括任何局部变量、参数和其他上下文,都将成为每个嵌入式函数对象的内部状态的一部分,甚至在外部函数的执行和退出之后。
请看下面的例子:

复制代码代码如下所示:
var I,list = };
对于(i = 0;i < 2;i=1){
List.push(function(){()
console.log(我);
});
}
list.foreach(function(函数){)
Func();
});


我们将得到两个2 ,而不是预期的1 和2

我们将代码更改为使用闭包来解决问题:

复制代码代码如下所示:
var I,list = };
对于(i = 0;i < 2;i=1){
List.push((功能(J){)
返回函数(){
console.log(J);
};
})(一);
}
list.foreach(function(函数){)
Func();
});


外层的立即执行的函数接受一个参数变量,它的功能在参数J的形式存在,它指的是在返回的内部函数的名称,相同的参考。在外部函数的执行和退出,j(此时它的值是当前I值)保存为其内在功能状态的一部分。