只需五句话搞定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 相关文章推荐
prototype Element学习笔记(Element篇三)
Oct 26 Javascript
IE中createElement需要注意的一个问题
Jul 13 Javascript
从jquery的过滤器.filter()方法想到的
Sep 29 Javascript
JS获取select-option-text_value的方法
Dec 26 Javascript
jquery sortable的拖动方法示例详解
Jan 16 Javascript
容易造成JavaScript内存泄露几个方面
Sep 04 Javascript
innerHTML中标签可以换行的方法汇总
Aug 14 Javascript
javascript轮播图算法
Oct 21 Javascript
js/jquery控制页面动态加载数据 滑动滚动条自动加载事件的方法
Feb 08 Javascript
微信小程序swiper组件用法实例分析【附源码下载】
Dec 07 Javascript
老生常谈JavaScript获取CSS样式的方法(兼容各浏览器)
Sep 19 Javascript
微信小程序+腾讯地图开发实现路径规划绘制
May 22 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中设置、使用、删除Cookie的解决方法
2013/05/06 PHP
JavaScript中Math对象使用说明
2008/01/16 Javascript
Firefox getBoxObjectFor getBoundingClientRect联系
2008/10/26 Javascript
动态载入/删除/更新外部 JavaScript/Css 文件的代码
2010/07/03 Javascript
使用jquery自定义鼠标样式满足个性需求
2013/11/05 Javascript
让input框实现类似百度的搜索提示(基于jquery事件监听)
2014/01/31 Javascript
js实现鼠标触发图片抖动效果的方法
2015/02/27 Javascript
Bootstrap学习笔记之css组件(3)
2016/06/07 Javascript
关于使用js算总价的问题
2017/06/23 Javascript
React中jquery引用的实现方法
2017/09/12 jQuery
浅谈Vue网络请求之interceptors实际应用
2018/02/28 Javascript
10分钟上手vue-cli 3.0 入门介绍
2018/04/04 Javascript
原生JS实现简单的倒计时功能示例
2018/08/30 Javascript
Vue项目部署在Spring Boot出现页面空白问题的解决方案
2018/11/26 Javascript
微信小程序使用map组件实现路线规划功能示例
2019/01/22 Javascript
微信小程序基于picker实现级联菜单
2019/02/15 Javascript
详解Vue demo实现商品列表的展示
2019/05/07 Javascript
Angular8 Http拦截器简单使用教程
2019/08/20 Javascript
vue开发移动端底部导航条功能
2020/04/08 Javascript
js实现表单项的全选、反选及删除操作示例
2020/06/05 Javascript
vue data变量相互赋值后被实时同步的解决步骤
2020/08/05 Javascript
Vue实现多页签组件
2021/01/14 Vue.js
Python中的作用域规则详解
2015/01/30 Python
在Python中使用poplib模块收取邮件的教程
2015/04/29 Python
python实现将一个数组逆序输出的方法
2018/06/25 Python
python 通过麦克风录音 生成wav文件的方法
2019/01/09 Python
python实现BP神经网络回归预测模型
2019/08/09 Python
Python 异步协程函数原理及实例详解
2019/11/13 Python
pytorch 计算Parameter和FLOP的操作
2021/03/04 Python
纯CSS3实现自定义Tooltip边框涂鸦风格的教程
2014/11/05 HTML / CSS
迪士尼英国官方商店:shopDisney UK
2019/09/21 全球购物
请解释在new与override的区别
2012/10/29 面试题
公司周年庆典邀请函
2014/01/12 职场文书
2014年小学教研工作总结
2014/12/06 职场文书
2014年班级工作总结范文
2014/12/23 职场文书
辩论赛开场白大全(主持人+辩手)
2015/05/29 职场文书