JavaScript的作用域一直以来是前端开发中比较难以理解的知识点,对于JavaScript的作用域主要记住几句话,走遍天下都不怕...

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

在Java或C#中存在块级作用域,即:大括号也是一个作用域。

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

Java

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

C#

在JavaScript语言中无块级作用域

1
2
3
4
5
6
7
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中的每个函数作为一个作用域,如果出现函数嵌套函数,则就会出现作用域链。

1
2
3
4
5
6
7
8
9
10
11
xo = 'alex';
  
function Func(){
    var xo = "seven";
    function inner(){
        var xo = 'alvin';
        console.log(xo);
    }
    inner();
}
Func();

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

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

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

JavaScript的作用域在被执行之前已经创建,日后再去执行时只需要按照作用域链去寻找即可。

示例一:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
xo = 'alex';
 
function Func(){
    var xo = "seven";
    function inner(){
 
        console.log(xo);
    }
    return inner;
}
 
var ret = Func();
ret();
// 输出结果: seven

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

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

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

示例二:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
xo = 'alex';
 
function Func(){
    var xo = "eirc";
    function inner(){
 
        console.log(xo);
    }
    xo = 'seven';
    return inner;
}
 
var ret = Func();
ret();
// 输出结果: seven

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

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

不同的时,在执行 var ret = Func(); 时,Func作用域中的xo变量的值已经由 “eric” 被重置为 “seven”,所以之后再执行 ret(); 时,就只能找到“seven”。

示例三:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
xo = 'alex';<br>
function Bar(){
    console.log(xo);
}
 
function Func(){
    var xo = "seven";
     
    return Bar;
}
 
var ret = Func();
ret();
// 输出结果: alex

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

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

当执行 ret(); 时,ret代指的Bar函数,而Bar函数的作用域链已经存在:全局作用域 -> Bar函数作用域,所以,执行时会根据已经存在的作用域链去寻找。

五、声明提前

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

1
2
console.log(xxoo);
// 报错:Uncaught ReferenceError: xxoo is not defined

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

1
2
3
var xxoo;
console.log(xxoo);
// 输出:undefined

在函数内如果这么写:

1
2
3
4
5
6
7
function Foo(){
    console.log(xo);
    var xo = 'seven';
}
 
Foo();
// 输出:undefined

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

JS作用域就这么几句话的更多相关文章

  1. 五句话搞定JavaScript作用域

    JavaScript的作用域一直以来是前端开发中比较难以理解的知识点,对于JavaScript的作用域主要记住几句话,走遍天下都不怕... 一.“JavaScript中无块级作用域” 在Java或C# ...

  2. 【】五句话搞定JavaScript作用域

    JavaScript的作用域一直以来是前端开发中比较难以理解的知识点,对于JavaScript的作用域主要记住几句话,走遍天下都不怕... 一.“JavaScript中无块级作用域” 在Java或C# ...

  3. 五句话搞定JavaScript作用域(ES5)

    JavaScript的作用域一直以来是前端开发中比较难以理解的知识点,对于JavaScript的作用域主要记住几句话,走遍天下都不怕... 一.“JavaScript中无块级作用域” 在Java或C# ...

  4. 5句话搞定ES5作用域

    JavaScript的作用域一直以来是前端开发中比较难以理解的知识点,对于JavaScript的作用域主要记住几句话,走遍天下都不怕... 一.“JavaScript中无块级作用域” 在Java或C# ...

  5. 五句话搞定JavaScript作用域【转】

    JavaScript的作用域一直以来是前端开发中比较难以理解的知识点,对于JavaScript的作用域主要记住几句话,走遍天下都不怕... 一.“JavaScript中无块级作用域” 在Java或C# ...

  6. 160630、五句话搞定JavaScript作用域

    JavaScript的作用域一直以来是前端开发中比较难以理解的知识点,对于JavaScript的作用域主要记住几句话,走遍天下都不怕.   一.“JavaScript中无块级作用域” 在Java或C# ...

  7. 【Python之路】特别篇--五句话搞定JavaScript作用域

    JavaScript的作用域一直以来是前端开发中比较难以理解的知识点,对于JavaScript的作用域主要记住几句话,走遍天下都不怕... 一.“JavaScript中无块级作用域” 在Java或C# ...

  8. 让png在ie下正常显示 用到了jquery插件DD_belatedPNG 但是在ie6中这句话 前面添加有效 后面移除无效 IE6 jq removeClass无效

    jQuery(this).addClass("background").siblings().removeClass("background") 导致IE6移除 ...

  9. 四句话总结JavaScript作用域

    上一篇文章中简单介绍了一下JS作用域,本篇将作进一步探究和总结. 前言:JavaScript的作用域一直以来都是前端开发中比较难以理解的知识点,JavaScript6中新引入了 let 关键字,用于指 ...

随机推荐

  1. 1131: [POI2008]Sta

    1131: [POI2008]Sta Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 783  Solved: 235[Submit][Status] ...

  2. 表格和echart二级联动,并通过点击echart高亮图标单元格

    html 部分 <!DOCTYPE html><html><head lang="en"> <meta charset="UTF ...

  3. JavaWeb之Servlet总结

    今天上班居然迟到了,昨天失眠了,看完吐槽大会实在不知道做些什么,刚好朋友给我发了两个JavaWeb的练习项目,自己就又研究了下,三四点才睡,可能周日白天睡的太多了,早上醒来已经九点多了,立马刷牙洗脸头 ...

  4. H5 内联 SVG

    HTML5 内联 SVG HTML5 画布 HTML5 画布 vs SVG HTML5 支持内联 SVG. 什么是SVG? SVG 指可伸缩矢量图形 (Scalable Vector Graphics ...

  5. Cordova框架基本原理

    最近在做混编项目,也是从项目里开始接触Cordova框架,网上很多帖子都总结的很好,我还是要总结一下,便于加深一下. Cordova框架是一个可以让JS与原生代码(包括 Android 的 java, ...

  6. Bootstrap 组件之 Navbar

    一.简介 Navbar 指导航条,它在移动设备上显示为折叠状态,在宽屏幕上水平展开.这里 是一个线上例子. 响应式导航条依赖 collapse 插件,定制 Bootstrap 时务必要包含. {设备的 ...

  7. servlet中的过滤器 国际化

    1. 过滤器 基本概念 过滤器是需要在xml中配置的. 为什么需用到过滤器? 项目开发中,经常会涉及到重复代码的实现! 注册 ----à Servlet [1. 设置编码] ----à  JSP 修改 ...

  8. ngrok localhost和http 的转换

    得益于老大的教导,今天又接触到一个有意思的东西,希望分享出来,供大家玩耍----“ngrok”: 乍一看还以为是angualar的新玩意,其实不是.这这家伙可以使本地开发的web应用,不用打包上传,也 ...

  9. 给 Virtualbox 中 Ubuntu 系统设置静态 IP ,让 DNS 配置信息不会在重启后被清除

    虚拟机网络选择 桥接网卡 模式. 主要涉及两个步骤: 1. 修改 /etc/network/interfaces 文件: 2. 修改 dns : 第一步,修改 interfaces 文件: sudo ...

  10. iOS开发之UITableView及cell重用

    1.UITanleview有的两种风格 一种是Plain,一种是Grouped,可以从这里设置风格: 他们样式分别如下: Plain: Grouped: 2.tableView展示数据的过程: (1) ...