只需五句话搞定JavaScript作用域(经典)


Posted in Javascript onJuly 26, 2016

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

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

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

public static void main ()
{ if(1==1){
String name = "seven";
}
System.out.println(name);
}// 报错
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

二、JavaScript采用函数作用域

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

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

三、JavaScript的作用域链

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

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

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

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

425762-20160707114743577-37359182.png

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

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

示例一:

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();】时,会根据已经存在的作用域链去寻找变量。

示例二:

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”。

示例三:

xo = 'alex';
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中如果不创建变量,直接去使用,则报错:

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

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

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

在函数内如果这么写:

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

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

以上所述是小编给大家介绍的只需五句话搞定JavaScript作用域(经典),希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
JS 建立对象的方法
Apr 21 Javascript
Javascript valueOf 使用方法
Dec 28 Javascript
Javascript 跨域访问解决方案
Feb 14 Javascript
extJs 常用到的增,删,改,查操作代码
Dec 28 Javascript
JavaScript 验证码的实例代码(附效果图)
Mar 22 Javascript
jQuery链使用指南
Jan 20 Javascript
原生js和jquery实现图片轮播特效
Apr 23 Javascript
JavaScript必知必会(五) eval 的使用
Jun 08 Javascript
JS实现页面打印(整体、局部)
Aug 18 Javascript
cordova入门基础教程及使用中遇到的一些问题总结
Nov 14 Javascript
Angular2进阶之如何避免Dom误区
Apr 02 Javascript
vue-router命名视图的使用讲解
Jan 19 Javascript
第一次接触神奇的Bootstrap基础排版
Jul 26 #Javascript
js获取html的span标签的值方法(超简单)
Jul 26 #Javascript
js无法获取到html标签的属性的解决方法
Jul 26 #Javascript
jquery判断对象是否为空并遍历对象的简单实例
Jul 26 #Javascript
浅谈Javascript数据属性与访问器属性
Jul 26 #Javascript
js判断空对象的实例(超简单)
Jul 26 #Javascript
全面了解构造函数继承关键apply call
Jul 26 #Javascript
You might like
php empty,isset,is_null判断比较(差异与异同)
2010/10/19 PHP
php的数组与字符串的转换函数整理汇总
2013/07/18 PHP
使用PHP备份MYSQL数据的多种方法
2014/01/15 PHP
laravel实现前后台路由分离的方法
2019/10/13 PHP
jQuery live
2009/05/15 Javascript
jQuery Ajax使用 全解析
2010/12/15 Javascript
JavaScript高级程序设计 阅读笔记(十三) js定义类或对象
2012/08/14 Javascript
JS验证邮箱格式是否正确的代码
2013/12/05 Javascript
利用JQuery和Servlet实现跨域提交请求示例分享
2014/02/12 Javascript
javascript的事件触发器介绍的实现
2014/06/05 Javascript
jQuery如何将选中的对象转化为原始的DOM对象
2014/06/09 Javascript
事件委托与阻止冒泡阻止其父元素事件触发
2014/09/02 Javascript
Node.js实现数据推送
2016/04/14 Javascript
JavaScript数组去重由慢到快由繁到简(优化篇)
2016/08/26 Javascript
Easyui Tree获取当前选择节点的所有顶级父节点
2017/02/14 Javascript
js中apply和Math.max()函数的问题及区别介绍
2018/03/27 Javascript
node.js实现http服务器与浏览器之间的内容缓存操作示例
2020/02/11 Javascript
详解Python异常处理中的Finally else的功能
2017/12/29 Python
python ansible服务及剧本编写
2017/12/29 Python
python批量设置多个Excel文件页眉页脚的脚本
2018/03/14 Python
Sanic框架蓝图用法实例分析
2018/07/17 Python
解决.ui文件生成的.py文件运行不出现界面的方法
2019/06/19 Python
css3中新增的样式使用示例附效果图
2014/08/19 HTML / CSS
html5读取本地文件示例代码
2014/04/22 HTML / CSS
新秀丽拉杆箱美国官方网站:Samsonite美国
2016/07/25 全球购物
描述Cookie和Session的作用,区别和各自的应用范围,Session工作原理
2015/03/25 面试题
阿里巴巴的Oracle DBA笔试题答案-SQL tuning类
2016/04/03 面试题
C#如何判断当前用户是否输入某个域
2015/12/07 面试题
简单的JAVA编程面试题
2013/03/19 面试题
医学生个人求职信范文
2013/09/24 职场文书
网络技术专业求职信
2014/05/02 职场文书
婚纱店策划方案
2014/05/22 职场文书
关于安全的标语
2014/06/10 职场文书
房屋买卖委托书格式范本格式
2014/10/13 职场文书
党的群众路线教育实践活动个人整改措施材料
2014/11/04 职场文书
为什么阅读对所有年龄段的孩子都很重要?
2019/07/08 职场文书