JS作用域就这么几句话
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作用域就这么几句话的更多相关文章
- 五句话搞定JavaScript作用域
JavaScript的作用域一直以来是前端开发中比较难以理解的知识点,对于JavaScript的作用域主要记住几句话,走遍天下都不怕... 一.“JavaScript中无块级作用域” 在Java或C# ...
- 【】五句话搞定JavaScript作用域
JavaScript的作用域一直以来是前端开发中比较难以理解的知识点,对于JavaScript的作用域主要记住几句话,走遍天下都不怕... 一.“JavaScript中无块级作用域” 在Java或C# ...
- 五句话搞定JavaScript作用域(ES5)
JavaScript的作用域一直以来是前端开发中比较难以理解的知识点,对于JavaScript的作用域主要记住几句话,走遍天下都不怕... 一.“JavaScript中无块级作用域” 在Java或C# ...
- 5句话搞定ES5作用域
JavaScript的作用域一直以来是前端开发中比较难以理解的知识点,对于JavaScript的作用域主要记住几句话,走遍天下都不怕... 一.“JavaScript中无块级作用域” 在Java或C# ...
- 五句话搞定JavaScript作用域【转】
JavaScript的作用域一直以来是前端开发中比较难以理解的知识点,对于JavaScript的作用域主要记住几句话,走遍天下都不怕... 一.“JavaScript中无块级作用域” 在Java或C# ...
- 160630、五句话搞定JavaScript作用域
JavaScript的作用域一直以来是前端开发中比较难以理解的知识点,对于JavaScript的作用域主要记住几句话,走遍天下都不怕. 一.“JavaScript中无块级作用域” 在Java或C# ...
- 【Python之路】特别篇--五句话搞定JavaScript作用域
JavaScript的作用域一直以来是前端开发中比较难以理解的知识点,对于JavaScript的作用域主要记住几句话,走遍天下都不怕... 一.“JavaScript中无块级作用域” 在Java或C# ...
- 让png在ie下正常显示 用到了jquery插件DD_belatedPNG 但是在ie6中这句话 前面添加有效 后面移除无效 IE6 jq removeClass无效
jQuery(this).addClass("background").siblings().removeClass("background") 导致IE6移除 ...
- 四句话总结JavaScript作用域
上一篇文章中简单介绍了一下JS作用域,本篇将作进一步探究和总结. 前言:JavaScript的作用域一直以来都是前端开发中比较难以理解的知识点,JavaScript6中新引入了 let 关键字,用于指 ...
随机推荐
- 在node中使用 ES6
ES6+ 太棒了,但是很多高级功能node是不支持的,就需要使用babel转换成ES5, 1.安装babel依赖 npm install babel-core --save-dev 2.安装babel ...
- webots自学笔记(四)传感器API使用、查看官方文档
原创文章,来自“博客园,_阿龙clliu” http://www.cnblogs.com/clliu/,转载请注明原文章出处. 不能说webots的学习资料少,只能说 ...
- 列表总结Canvas和SVG的区别
参考链接: 菜鸟教程 HTML5 内联SVG 经典面试题(讨论canvas与svg的区别) Canvas | SVG ---|--- 通过 JavaScript 来绘制 2D 图形|是一种使用 XML ...
- Android之万能播放器解码框架Vitamio的介绍及使用
一.简介 Vitamio能够流畅播放720P甚至1080P高清MKV,FLV,MP4,MOV,TS,RMVB等常见格式的视频,还可以在Android 与 iOS 上跨平台支持 MMS, RTSP, R ...
- 强大的版本管理工具 Git
Git 简介 git 是一款免费.开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目.是 linux 创始人 Linus Torvalds 为了帮助管理 linux 内核开发而开发的一个开 ...
- MyBatis快速入门(1):搭建环境和单表映射
一.MyBatis简介 一说起对象关系映射框架,大家第一时间想到的肯定是Hibernate.Hibernate作为一个著名的框架,功能十分强大.我们只需要配置好实体类和数据表之间的关系,Hibe ...
- org.springframework.beans.factory.BeanDefinitionStoreException异常
1.下面是我遇到的异常信息: 2017-03-25 18:01:11,322 [localhost-startStop-1][org.springframework.web.context.Conte ...
- 玩玩 Nginx 2-----给Nginx添加第三方模块(动态更新upstream)
接上一篇,我们在初始化安装的时候添加了nginx_lua模块,然后了解到nginx不可以动态加载模块,所以当你安装第三方模块的时候需要覆盖nginx文件.接下来一起看看如何安装nginx第 ...
- JQ实战一之烟花
本次的效果大概为当用户点击网页时,网页下方弹出一个类似烟花的长条条,然后在桌面上散开以达成类似烟花的特效.话不多说先上图. 首先布局,布局很简单 <style> body { backgr ...
- 9.Linux系统引导流程
一.Linux系统引导流程 当我们按下主机电源键的那时候开始,主板上的CMOS/BIOS模块将进行固件自检,以此检查各个硬件是否正确连接. 在Linux引导流程中,一般可以分为以下几个主要过程: 1. ...