Javascript 执行上下文和闭包-特定代码的问题
在这里,第17行和第18行的执行上下文是分开的,但将创建的闭包将引用“语言”的同一实例,因为函数在第15行返回,并且闭包中具有相同的“语言”。现在,由于第16行中函数“test”的初始化不同,第18行将具有不同的执行上下文以及不同的语言实例。因此,输出将是Javascript 执行上下文和闭包-特定代码的问题,javascript,closures,Javascript,Closures,在这里,第17行和第18行的执行上下文是分开的,但将创建的闭包将引用“语言”的同一实例,因为函数在第15行返回,并且闭包中具有相同的“语言”。现在,由于第16行中函数“test”的初始化不同,第18行将具有不同的执行上下文以及不同的语言实例。因此,输出将是 1. function test(language){ 2. return function(set){ 3. if(set) 4. { 5. language=set; 6.
1. function test(language){
2. return function(set){
3. if(set)
4. {
5. language=set;
6. console.log("Changed "+language);
7. }
8. else
9. {
10. console.log(language);
11. }
12. }
13. }
14.
15. var a=test("en");
16. var b=test("es");
17. a("Spanish");
18. a();
19. b();
但是现在,
Changed Spanish
Spanish
es
这里,第17行和第18行将具有不同的执行上下文,但具有相同的“语言”实例。但是“a”和“b”变量的闭包将有不同的“language”实例,就像前面的示例一样,即使值被“a”更改为“西班牙语”,调用“b”时显示的值仍然是“es”,因为b的“language”与a的“language”不同。但在这里,当我在第17行中将a的语言更改为“西班牙语”时,我检查了输出,b的“语言”也更改了,给出了如下输出:
1. function test(){ language = "English"
2. return function(set){
3. if(set)
4. {
5. language=set;
6. console.log("Changed "+language);
7. }
8. else
9. {
10. console.log(language);
11. }
12. }
13. }
14.
15. var a=test();
16. var b=test();
17. a("Spanish");
18. a();
19. b();
Changed Spanish
Spanish
Spanish
1. function test(){ var language = "English"
2. return function(set){
3. if(set)
4. {
5. language=set;
6. console.log("Changed "+language);
7. }
8. else
9. {
10. console.log(language);
11. }
12. }
13. }
14.
15. var a=test();
16. var b=test();
17. a("Spanish");
18. a();
19. b();
20. console.log(this.language)
现在,理解第一行和第二行是因为与第一个示例一样,所有“a”函数调用中都存在相同的“language”实例,但b的闭包必须具有不同的language实例。那么为什么输出不如下所示:
1. function test(){ language = "English"
2. return function(set){
3. if(set)
4. {
5. language=set;
6. console.log("Changed "+language);
7. }
8. else
9. {
10. console.log(language);
11. }
12. }
13. }
14.
15. var a=test();
16. var b=test();
17. a("Spanish");
18. a();
19. b();
Changed Spanish
Spanish
Spanish
1. function test(){ var language = "English"
2. return function(set){
3. if(set)
4. {
5. language=set;
6. console.log("Changed "+language);
7. }
8. else
9. {
10. console.log(language);
11. }
12. }
13. }
14.
15. var a=test();
16. var b=test();
17. a("Spanish");
18. a();
19. b();
20. console.log(this.language)
答案在于,在第二个代码片段的第1行中声明变量时不使用关键字
var
。正如在其他资源中发现的那样,如果我们按原样声明变量,那么它将在全局上下文中声明
更改代码如下:
Changed Spanish
Spanish
English
我在代码中添加了额外的第20行,以证明该变量不在窗口范围内,因此上述代码段的输出如下所示:
1. function test(){ language = "English"
2. return function(set){
3. if(set)
4. {
5. language=set;
6. console.log("Changed "+language);
7. }
8. else
9. {
10. console.log(language);
11. }
12. }
13. }
14.
15. var a=test();
16. var b=test();
17. a("Spanish");
18. a();
19. b();
Changed Spanish
Spanish
Spanish
1. function test(){ var language = "English"
2. return function(set){
3. if(set)
4. {
5. language=set;
6. console.log("Changed "+language);
7. }
8. else
9. {
10. console.log(language);
11. }
12. }
13. }
14.
15. var a=test();
16. var b=test();
17. a("Spanish");
18. a();
19. b();
20. console.log(this.language)
在问题的第二个代码片段中,“language”变量出现在全局范围内,因此它将返回“西班牙语”,而不是未定义。省略
var
,let
或const
,导致2020年仍然出现错误。使用let language=“English”
,并转到严格模式,在该模式下,这将抛出并使您立即注意到问题。是的,@ASDFGerte。我在回答中补充了同样的问题,并作了更多解释。请检查一下。