只需五句话搞定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 相关文章推荐
jquery构造器的实现代码小结
May 16 Javascript
JavaScript 基础篇之对象、数组使用介绍(三)
Apr 07 Javascript
javascript中的throttle和debounce浅析
Jun 06 Javascript
贴近用户体验的Jquery日期、时间选择插件
Aug 19 Javascript
js实现3D图片逐张轮播幻灯片特效代码分享
Sep 09 Javascript
学习JavaScript设计模式(继承)
Nov 26 Javascript
浅谈javascript中关于日期和时间的基础知识
Jul 13 Javascript
详解Angular 中 ngOnInit 和 constructor 使用场景
Jun 22 Javascript
jquery如何实现点击空白处隐藏元素
Dec 05 jQuery
利用JQUERY实现多个AJAX请求等待的实例
Dec 14 jQuery
JS控制GIF图片的停止与显示
Oct 24 Javascript
Vue + Node.js + MongoDB图片上传组件实现图片预览和删除功能详解
Apr 29 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
评分9.0以上的动画电影,剧情除了经典还很燃
2020/03/04 日漫
cakephp2.X多表联合查询join及使用分页查询的方法
2017/02/23 PHP
php批量转换文件夹下所有文件编码的函数类
2017/08/06 PHP
基于php编程规范(详解)
2017/08/17 PHP
PHP有序表查找之插值查找算法示例
2018/02/10 PHP
thinkphp5.1框架实现格式化mysql时间戳为日期的方式小结
2019/10/10 PHP
仿新浪微博登陆邮箱提示效果的js代码
2013/08/02 Javascript
jQuery中:image选择器用法实例
2015/01/03 Javascript
完善的jquery处理机制
2016/02/21 Javascript
AngularJS教程 ng-style 指令简单示例
2016/08/03 Javascript
深入理解AngularJS中的ng-bind-html指令和$sce服务
2016/09/08 Javascript
js通过指定下标或指定元素进行删除数组的实例
2017/01/12 Javascript
利用nodejs监控文件变化并使用sftp上传到服务器
2017/02/18 NodeJs
jQuery树控件zTree使用方法详解(一)
2017/02/28 Javascript
Javascript 详解封装from表单数据为json串进行ajax提交
2017/03/29 Javascript
深入理解JavaScript继承的多种方式和优缺点
2017/05/12 Javascript
Node.js Buffer模块功能及常用方法实例分析
2019/01/05 Javascript
Vue事件处理原理及过程详解
2020/03/11 Javascript
JS实现拖拽元素时与另一元素碰撞检测
2020/08/27 Javascript
python进阶教程之循环相关函数range、enumerate、zip
2014/08/30 Python
解析Python中的异常处理
2015/04/28 Python
python验证码识别的实例详解
2016/09/09 Python
python中int与str互转方法
2018/07/02 Python
Python中staticmethod和classmethod的作用与区别
2018/10/11 Python
python 使用poster模块进行http方式的文件传输到服务器的方法
2019/01/15 Python
python实现画五角星和螺旋线的示例
2019/01/20 Python
Python 实现数据结构中的的栈队列
2019/05/16 Python
python实现sm2和sm4国密(国家商用密码)算法的示例
2020/09/26 Python
简述Html5 IphoneX 适配方法
2018/02/08 HTML / CSS
建筑工地门卫岗位职责
2014/04/30 职场文书
工商管理专业自荐信
2014/06/03 职场文书
2014年勤工助学工作总结
2014/11/24 职场文书
政协委员个人总结
2015/03/03 职场文书
运动会1000米加油稿
2015/07/21 职场文书
导游词之崇武古城
2019/10/07 职场文书
MYSQL 的10大经典优化案例场景实战
2021/09/14 MySQL