只需五句话搞定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 隐藏/显示指定的区域附HTML元素【legend】用法
Mar 05 Javascript
js获取Get值的方法
Sep 29 Javascript
EasyUI学习之DataGird分页显示数据
Dec 29 Javascript
js 单引号替换成双引号,双引号替换成单引号的实现方法
Feb 16 Javascript
jQuery插件zTree实现删除树子节点的方法示例
Mar 08 Javascript
jquery.flot.js简单绘制折线图用法示例
Mar 13 Javascript
详解Angular.js数据绑定时自动转义html标签及内容
Mar 30 Javascript
bootstrap如何让dropdown menu按钮式下拉框长度一致
Apr 10 Javascript
利用Javascript开发一个二维周视图日历
Dec 14 Javascript
详解npm 配置项registry修改为淘宝镜像
Sep 07 Javascript
JavaScript变量基本使用方法实例分析
Nov 15 Javascript
面试中canvas绘制图片模糊图片问题处理
Mar 13 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
探讨Hessian在PHP中的使用分析
2013/06/13 PHP
浅谈php和.net的区别
2014/09/28 PHP
关于jQuery UI 使用心得及技巧
2012/10/10 Javascript
本地图片预览(支持IE6/IE7/IE8/Firefox3)经验总结
2013/03/25 Javascript
js实现表单Radio切换效果的方法
2015/08/17 Javascript
第一次接触神奇的Bootstrap基础排版
2016/07/26 Javascript
详解Jquery EasyUI tree 的异步加载(遍历指定文件夹,根据文件夹内的文件生成tree)
2017/02/11 Javascript
Vue分页组件实例代码
2017/04/17 Javascript
Vue实现virtual-dom的原理简析
2017/07/10 Javascript
Vue组件选项props实例详解
2017/08/18 Javascript
jquery实现图片跟随鼠标的实例
2017/10/17 jQuery
通过封装scroll.js 获取滚动条的值
2018/07/13 Javascript
详解vue-element Tree树形控件填坑路
2019/03/26 Javascript
Vue 权限控制的两种方法(路由验证)
2019/08/16 Javascript
vue v-for直接循环数字实例
2019/11/07 Javascript
微信小程序button标签open-type属性原理解析
2020/01/21 Javascript
Python对象的深拷贝和浅拷贝详解
2014/08/25 Python
Python操作串口的方法
2015/06/17 Python
python中for循环输出列表索引与对应的值方法
2018/11/07 Python
分享8个非常流行的 Python 可视化工具包
2019/06/05 Python
使用Python计算玩彩票赢钱概率
2019/06/26 Python
详解Django配置优化方法
2019/11/18 Python
在pytorch中对非叶节点的变量计算梯度实例
2020/01/10 Python
Python实现给PDF添加水印的方法
2021/01/25 Python
美国婴儿用品及配件购买网站:Munchkin
2019/04/03 全球购物
琳达·法罗眼镜英国官网:Linda Farrow英国
2021/01/19 全球购物
在SQL Server中创建数据库主要有那种方式
2013/09/10 面试题
大学生职业生涯规划书模板
2014/01/18 职场文书
酒店秘书求职信范文
2014/02/17 职场文书
成绩单公证书
2014/04/10 职场文书
妇女工作先进事迹
2014/08/17 职场文书
弘扬焦裕禄精神走群众路线思想汇报
2014/09/12 职场文书
商标侵权律师函
2015/05/27 职场文书
vue组件冲突之引用另一个组件出现组件不显示的问题
2022/04/13 Vue.js
详解如何使用Nginx解决跨域问题
2022/05/06 Servers
Fluentd搭建日志收集服务
2022/09/23 Servers