ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

JavaScript之作用域

2020-03-26 16:53:40  阅读:164  来源: 互联网

标签:xo 作用域 JavaScript ret var 函数


JavaScript的作用域一直以来都是前端开发中比较难以理解的知识点,对于JavaScript的作用域,记住下面五句话即可。

一,“JavaScript中无块级作用域”

在java或者c#中存在块级作用域,即:大括号也是一个作用域

java

public static void main ()
{
    if(1==1){
        String name = "seven";
    }
    System.out.println(name);
}
// 报错

C#

public static void Main()
{
    if(1==1){
        string name = "seven";
    }
    Console.WriteLine(name);
}
// 报错

  在JavaScript语言中无块级作用域

function Main(){
        if(1==1){
                var name = "seven";
        }
        console.log(name);
}
//输出:seven

  补充:标题之所以添加双引号是因为JavaScript6中新引入了let关键字,用于指定变量属于块级作用域。

 

二,JavaScript采用函数作用域

  在JavaScript中每个函数作为一个作用域,在外部无法访问内部作用域中的变量。

function Main(){
    var innerValue = 'seven';
}
  
Main();
  
console.log(innerValue);
  
// 报错:Uncaught ReferenceError: innerValue is not defined

 

三:JavaScript的作用域链

  由于JavaScript中的每个函数作为一个作用域,如果出现函数嵌套函数,就会出现作用域链。

xo = 'james';
   
function Func(){
    var xo = "seven";
    function inner(){
        var xo = 'durant';
        console.log(xo);
    }
    inner();
}
Func();

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

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

 

四,JavaScript的作用域链执行前已创建

示例一:

xo = 'james';
  
function Func(){
    var xo = "durant";
    function inner(){
  
        console.log(xo);
    }
    return inner;
}
  
var ret = Func();
ret();
// 输出结果: durant

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

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

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

示例二:

xo = 'james';
 
        function Func(){
            var xo = "durant";
            function inner(){
 
                console.log(xo);
            }
            xo = "curry";
            return inner;
        }
 
        var ret = Func();
        ret();
//输出结果:curry

上述代码和示例一的目的一样,也是强调在函数被调用之前作用域链已经存在:

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

不同的是,在执行var ret = Func()时候,Func作用域中的xo变量的值已经由durant被重置为curry,所以之后在执行ret()的时候,就只能找到curry了。

示例三:

xo = 'james';
 
        function Func1(){
           console.log(xo);
        }
 
        function Func2(){
            var xo ='durant';
            return Func1;
        }
 
        var ret = Func2();
        ret();
//输出结果:james

上述代码中,在函数被执行之前已经创建了两条作用域链:

  • 全局作用域 -> Func1函数作用域
  • 全局作用域 -> Func2函数作用域

当执行ret()时候,ret代指的是Func1函数,而Func1函数的作用域链已经存在:全局作用域大于Func1()函数作用域,所以,执行的时候会根据已经存在的作用域链去寻找。

 

五,声明提前

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

console.log(a);
// 报错:Uncaught ReferenceError: a is not defined

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

var ret;
console.log(ret);
// 输出:undefined

在函数中如果这么写:

function Foo(){
    console.log(ret);
    var ret = 'seven';
}
  
Foo();
// 输出:undefined

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

标签:xo,作用域,JavaScript,ret,var,函数
来源: https://www.cnblogs.com/tu240302975/p/12575438.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有