只需五句话搞定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 网页水印(非图片水印)实现代码
Mar 01 Javascript
基于jquery创建的一个图片、视频缓冲的效果样式插件
Aug 28 Javascript
jQuery $.data()方法使用注意细节
Dec 31 Javascript
鼠标滚轮控制网页横向移动实现思路
Mar 22 Javascript
JS数组合并push与concat区别分析
Dec 17 Javascript
JS判断iframe是否加载完成的方法
Aug 03 Javascript
谈谈对JavaScript原生拖放的深入理解
Sep 20 Javascript
JS实现Ajax的方法分析
Dec 20 Javascript
微信JS SDK接入的几点注意事项(必看篇)
Jun 23 Javascript
使用Vue写一个datepicker的示例
Jan 27 Javascript
基于vue开发微信小程序mpvue-docs跳转页面功能
Apr 10 Javascript
JS实现canvas简单小画板功能
Jun 23 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 获得汉字拼音首字母的函数
2009/08/01 PHP
PHP编码转换函数 自动转换字符集支持数组转换
2012/12/16 PHP
thinkphp实现数组分页示例
2014/04/13 PHP
Yii2 rbac权限控制之菜单menu实例教程
2016/04/28 PHP
PHP实现模拟http请求的方法分析
2017/12/20 PHP
PHP receiveMail实现收邮件功能
2018/04/25 PHP
javascript 面向对象编程基础:继承
2009/08/21 Javascript
jquery+json 通用三级联动下拉列表
2010/04/19 Javascript
jQuery 表单验证扩展代码(一)
2010/10/11 Javascript
jQuery鼠标经过方形图片切换成圆边效果代码分享
2015/08/20 Javascript
JavaScript实战(原生range和自定义特效)简单实例
2016/08/21 Javascript
利用JQuery阻止事件冒泡
2016/12/01 Javascript
使用BootStrap实现悬浮窗口的效果
2016/12/13 Javascript
nodejs+websocket实时聊天系统改进版
2017/05/18 NodeJs
微信小程序实现图片放大预览功能
2020/10/22 Javascript
JS对象与json字符串相互转换实现方法示例
2018/06/14 Javascript
JavaScript 点击触发复制功能实例详解
2018/11/02 Javascript
详解VUE Element-UI多级菜单动态渲染的组件
2019/04/25 Javascript
Layui弹出层 加载 做编辑页面的方法
2019/09/16 Javascript
[08:47]DOTA2每周TOP10 精彩击杀集锦vol.6
2014/06/25 DOTA
python转换字符串为摩尔斯电码的方法
2015/07/06 Python
代码详解django中数据库设置
2019/01/28 Python
一行Python代码制作动态二维码的实现
2019/09/09 Python
解决jupyter notebook 前面书写后面内容消失的问题
2020/04/13 Python
Python图像识别+KNN求解数独的实现
2020/11/13 Python
selenium自动化测试入门实战
2020/12/21 Python
CSS3实现各种图形的示例代码
2016/10/19 HTML / CSS
Jacadi Paris英国官网:法国童装品牌
2019/08/09 全球购物
应聘护士自荐信
2013/10/21 职场文书
超市采购员岗位职责
2014/02/01 职场文书
幼师自我鉴定
2014/02/01 职场文书
自动化毕业生专业自荐书范文
2014/02/04 职场文书
班长竞选演讲稿
2014/04/24 职场文书
小学班长竞选稿
2015/11/20 职场文书
2019垃圾分类宣传口号汇总
2019/08/16 职场文书
Python 的 sum() Pythonic 的求和方法详细
2021/10/16 Python