只需五句话搞定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 相关文章推荐
javascript 设置某DIV区域内的checkbox复选框
Nov 30 Javascript
js中opener与parent的区别详细解析
Jan 14 Javascript
javascript三元运算符用法实例
Apr 16 Javascript
jquery+CSS实现的水平布局多级网页菜单效果
Aug 24 Javascript
jquery实现删除一个元素后面的所有元素功能
Dec 21 Javascript
js实现文本框输入文字个数限制代码
Dec 25 Javascript
JS中如何比较两个Json对象是否相等实例代码
Jul 13 Javascript
JavaScript中Number对象的toFixed() 方法详解
Sep 02 Javascript
javascript读取文本节点方法小结
Dec 15 Javascript
详谈AngularJs 控制器、数据绑定、作用域
Jul 09 Javascript
微信小程序实现的涂鸦功能示例【附源码下载】
Jan 12 Javascript
JS 封装父页面子页面交互接口的实例代码
Jun 25 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生成QRcode实例
2014/09/22 PHP
浅析Yii2 GridView实现下拉搜索教程
2016/04/22 PHP
IE浏览器IFrame对象内存不释放问题解决方法
2014/08/22 Javascript
JQuery radio(单选按钮)操作方法汇总
2015/04/15 Javascript
jQuery密码强度检测插件passwordStrength用法实例分析
2015/10/30 Javascript
JavaScript数组的一些奇葩行为
2016/01/25 Javascript
js删除局部变量的实现方法
2016/06/25 Javascript
js判断出两个字符串最大子串的函数实现方法
2016/11/01 Javascript
微信小程序 后台https域名绑定和免费的https证书申请详解
2016/11/10 Javascript
JavaScript实现Fly Bird小游戏
2016/12/15 Javascript
vue2.0实现导航菜单切换效果
2017/05/08 Javascript
Three.js利用Detector.js插件如何实现兼容性检测详解
2017/09/26 Javascript
在 Node.js 中使用 async 函数的方法
2017/11/17 Javascript
基于vue-upload-component封装一个图片上传组件的示例
2018/10/16 Javascript
从Node.js事件触发器到Vue自定义事件的深入讲解
2020/06/26 Javascript
[45:52]2018DOTA2亚洲邀请赛 4.1小组赛 A组加赛 LGD vs Liquid
2018/04/02 DOTA
pyside写ui界面入门示例
2014/01/22 Python
调试Python程序代码的几种方法总结
2015/04/28 Python
python结合shell查询google关键词排名的实现代码
2016/02/27 Python
通过Python使用saltstack生成服务器资产清单
2016/03/01 Python
浅析python中的分片与截断序列
2016/08/09 Python
Python中if elif else及缩进的使用简述
2018/05/31 Python
使用Python的Dataframe取两列时间值相差一年的所有行方法
2018/07/10 Python
DRF跨域后端解决之django-cors-headers的使用
2019/01/27 Python
谈谈Python中的while循环语句
2019/03/10 Python
在Python中使用MySQL--PyMySQL的基本使用方法
2019/11/19 Python
PyQt5中多线程模块QThread使用方法的实现
2020/01/31 Python
使用Keras加载含有自定义层或函数的模型操作
2020/06/10 Python
Python实现小黑屋游戏的完整实例
2021/01/06 Python
python 如何读、写、解析CSV文件
2021/03/03 Python
物理分数没达标检讨书
2014/09/13 职场文书
志愿者事迹材料
2014/12/26 职场文书
学期个人工作总结
2015/02/13 职场文书
文明旅游倡议书
2015/04/28 职场文书
JavaScript 防篡改对象的用法示例
2021/04/24 Javascript
【DOTA2】总决赛血虐~ XTREME GAMING vs MAGMA - OGA DOTA PIT 2022 CN
2022/04/02 DOTA