js作用域理解 function(){} var

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了js作用域理解 function(){} var相关的知识,希望对你有一定的参考价值。

在coding过程中遇到过下面的情况:

 1 var test1 = function(){
 2     var c=4;
 3     test2();
 4 };
 5 
 6 var test2 = function(){
 7     console.log(c);
 8 };
 9     
10 test1();

思考一下,7行会conasole出什么?4 吗?实际上却是 c is not defined。

技术分享

而当代码如下的时候,

 1 var test1 = function(){
 2     var c=4
 3     var test2 = function(){
 4         console.log(c);
 5     };
 6     
 7     test2();
 8 };
 9 
10 
11 test1();

或者代码如下

 1 var test1 = function(){
 2     c=4
 3     test2();
 4 };
 5 
 6 var test2 = function(){
 7     console.log(c);
 8 };
 9     
10 test1();

console 出的就是4。

技术分享

 

这是为什么呢?

首先,让我们明白两个知识点:

1、js作用域:作用域就作用范围分为全局作用域和局部作用域。

A、全局作用域:从定义变量的位置开始到本源文件结束。其中 a 就是一个全局变量,作用范围全局,所以在 4 和 6 都可以 console 出 3.

 1 var a = 3;
 2 
 3 var test3 = function(){
 4     console.log(a);
 5     var test4 = function (){
 6         console.log(a);
 7     };
 8     test4();
 9 };
10 
11 test3();

技术分享

B、局部作用域。在本函数范围内。通俗一点说,局部变量只能在定义它的函数内部使用,而不能在其它函数内使用这个变量。

 1 var test3 = function(){
 2     console.log(a);
 3     var test4 = function (){
 4         var a = 3;
 5 
 6         console.log(a);
 7     };
 8     test4();
 9 };
10 
11 test3();

 

我们把上一个代码中的 var a = 3;移到第四行,就会出现 2 行的console 中的 a 没有定义的报错,这是因为 a 是在 test4 这个函数中定义的,所以外部的函数test3不能访问包裹在里面的 test4 定义的 a。

技术分享

 

这就又出现了一个概念:内部函数可以访问外部函数的变量,外部不能访问内部函数的变量。

 1 var test3 = function(){
 2     var a = 3;
 3     console.log(a);
 4     var test4 = function (){
 5         console.log(a);
 6     };
 7     test4();
 8 };
 9 
10 test3();

 

我们再把 var a = 3; 移到第2行,那么就可以正常打出 3 行和 5 行的console。说明 test4 可以访问外部的 test3 的定义的变量 a。

技术分享

 

2、 var 与不 var 的区别。有var声明的是局部变量,没var的声明的是全局变量。

 

好了 ,现在回到最开始的问题上,再贴一次代码,方便瞅。

 1 var test1 = function(){
 2     var c=4;
 3     test2();
 4 };
 5 
 6 var test2 = function(){
 7     console.log(c);
 8 };
 9     
10 test1();

 

这个是console不出来的,原因是什么呢?

总共有两个函数 test 1 和 test 2 ,各有各的局部作用域,其中 var c = 4 在 test 1 中,而非在 test 2 中,所以 test 2 不能够调用在 test 1 中的变量 c。那你会说我再第三行调用了 test 2  这个函数啊?那是因为 test2();是个指针,指向位于下方的 test 2 函数,但是指针只能调用对象的内存地址,你可以使用它的值,但你不能改变或调用其内部实现时的任何变量。简单来说,就是你只可以调用这个函数的值,但不能改变它,不能影响它。

 

而当没有 var 声明的时候,也就是第三段代码:

 1 var test1 = function(){
 2     c=4
 3     test2();
 4 };
 5 
 6 var test2 = function(){
 7     console.log(c);
 8 };
 9     
10 test1();

 

虽然没有 var 的字样,但并不代表它没有声明,只不过这个时候声明了一个全局变量,他的作用域是全局。所以下方的 test 2 函数可以调用 c = 4。

再或者代码如第二段:

 1 var test1 = function(){
 2     var c=4
 3     var test2 = function(){
 4         console.log(c);
 5     };
 6     
 7     test2();
 8 };
 9 
10 
11 test1();

 

同理,不看 test 1 那么 就相当于

1 var c=4;
2 var test2 = function(){
3     console.log(c);
4 };
5       
6 test2(); 

c 就是 全局变量,test 2 当然可以使用 c 啦~ 加上 test 1 之后,也就是对于 test 2 来说 test 1 函数内声明的变量 是个全局变量,在整个 test 1 中都可以调用。

 

完。

 

以上是关于js作用域理解 function(){} var的主要内容,如果未能解决你的问题,请参考以下文章

深度理解js中var let const 区别

关于预解释的理解

关于js的作用域,自我认知

js---07 js解析器作用域

我之理解js作用域,作用域链与变量提升

预解释