前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >四句话总结JavaScript作用域

四句话总结JavaScript作用域

作者头像
用户1432189
发布2018-09-05 10:03:32
4290
发布2018-09-05 10:03:32
举报
文章被收录于专栏:zingpLiu

上一篇文章中简单介绍了一下JS作用域,本篇将作进一步探究和总结。

前言:JavaScript的作用域一直以来都是前端开发中比较难以理解的知识点,JavaScript6中新引入了 let 关键字,用于指定变量属于块级作用域,本次先忽略这个点。

第一句话:JavaScript以函数作为作用域(忽略let)

  很多语言如c#,java都是以代码块作为作用域即大括号也是一个作用域,JavaScript却是以函数作为作用域,如果你对python比较了解,理解起来应该很easy。

在c#中下面的代码将直接报错:

代码语言:javascript
复制
 1 public void Func(){
 2     if(1==1){
 3         string name = 'Java';
 4                             
 5     }
 6     console.writeline(name);
 7                         
 8 }
 9 Func()
10  // 报错    

在JavaScript语言中无块级作用域:

代码语言:javascript
复制
1 function Main(){
2     if(1==1){
3         var name = 'seven';
4     }
5     console.log(name);
6 }
7 // 输出: seven

我们先来回忆一下python的作用域(如果不会python可以跳过,不影响后面阅读):

代码语言:javascript
复制
 1 # 情况一:
 2 def func():
 3     if 1 == 1:
 4         name = 'alex'
 5     print(name)
 6 func()
 7 # 成功
 8 
 9 # 情况二:
10 def func():
11     if 1 == 1:
12         name = 'alex'
13     print(name)
14     
15 func()
16 print(name)
17 # // 报错

再来看看JavaScript采用函数作用域:

代码语言:javascript
复制
1 function Main(){
2     var innerValue = 'seven';
3 }
4  
5 Main();
6  
7 console.log(innerValue);
8  
9 // 报错:Uncaught ReferenceError: innerValue is not defined

  在JavaScript中每个函数作为一个作用域,在外部无法访问内部作用域中的变量。console.log(innerValue)访问函数Main()中的变量肯定是不行的。

第二句话:JavaScript函数的作用域在函数未被调用之前,已经创建

  在JavaScript中如果不创建(声明)变量,直接去使用,则报错:

代码语言:javascript
复制
1 console.log(x);
2 VM199:1 Uncaught ReferenceError: x is not defined(…)

  JavaScript中如果创建值而不赋值,则该值为 undefined,如:

代码语言:javascript
复制
1 var num;
2 console.log(num);
3 
4 //undefined

     了解了这个看看下面这个函数:

代码语言:javascript
复制
1 function func(){
2     if(1==1){
3         var name = 'alex';
4     }
5     console.log(name);
6 }

  在浏览器中直接输入这个函数会得到undefined,而不是报错,就说明变量name在函数调用之前就创建(声明)了,但没有被赋值。

第三句话:函数的作用域存在作用域链,并且也是在被调用之前创建

代码语言:javascript
复制
 1  1 <script>
 2  2     x = "alex";
 3  3     function func() {
 4  4         var x = "eric";
 5  5         function inner() {
 6  6             var x = "tony";
 7  7             console.log(x);
 8  8         }
 9  9         inner();
10 10     }
11 11     func();
12 12 </script>

输出结果是tony。

如上述代码则出现三个作用域组成的作用域链,如果出现作用域链后,那么寻找变量时候就会出现顺序,对于上述实例:

当执行console.log(xo)时,其寻找顺序为根据作用域链从内到外的优先级寻找,如果内层没有就逐步向上找,直到没找到抛出异常。

 练习题1:

代码语言:javascript
复制
 1 x = "alex";
 2 function func() {
 3     var x = "eric";
 4     function inner() {
 5         console.log(x);
 6     }
 7     return inner;
 8 }
 9 var res = func();
10 res();

结果:eric

上述代码,在函数被调用之前作用域链已经存在:

  • 全局作用域 -> func函数作用域 -> inner函数作用域

当执行【ret();】时,由于其代指的是inner函数,此函数的作用域链在执行之前已经被定义为:全局作用域 -> Func函数作用域 -> inner函数作用域,所以,在执行【ret();】时,会根据已经存在的作用域链去寻找变量。

练习题2:

代码语言:javascript
复制
 1 x = "alex";
 2 function func() {
 3     var x = "eric";
 4     function inner() {
 5         console.log(x);
 6     }
 7     var x = 'tony';
 8     return inner;
 9 }
10 var res = func();
11 res();

结果:tony

第四句话: 函数内局部变量 声明提前

代码语言:javascript
复制
1 function func(){
2     console.log(xo);
3     var xo = 'alex';
4 } 
5       
6 func();
7 // undefined

上述代码,不报错而是输出 undefined,其原因是:JavaScript的函数在被执行之前,会将其中的变量全部声明,而不赋值。所以,相当于上述实例中,函数在“预编译”时,已经执行了var xo;所以上述代码中输出的是undefined。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016-11-25 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 第一句话:JavaScript以函数作为作用域(忽略let)
  • 第二句话:JavaScript函数的作用域在函数未被调用之前,已经创建
  • 第三句话:函数的作用域存在作用域链,并且也是在被调用之前创建
  • 第四句话: 函数内局部变量 声明提前
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档