只需五句话搞定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之旅 对象的原型链之由来
Aug 25 Javascript
js切换div css注意的细节
Dec 10 Javascript
JS前端框架关于重构的失败经验分享
Mar 17 Javascript
jquery弹出框的用法示例(一)
Aug 26 Javascript
jquery操作checkbox实现全选和取消全选
May 02 Javascript
jQuery中next方法用法实例
Apr 24 Javascript
js+html获取系统当前时间
Nov 10 Javascript
微信小程序实现图片压缩功能
Jan 26 Javascript
Vue.js项目中管理每个页面的头部标签的两种方法
Jun 25 Javascript
vue vue-Router默认hash模式修改为history需要做的修改详解
Sep 13 Javascript
JavaScript遍历数组的方法代码实例
Jan 14 Javascript
vue 使用插槽分发内容操作示例【单个插槽、具名插槽、作用域插槽】
Mar 06 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 mvc开发模式的感想
2011/06/28 PHP
openPNE常用方法分享
2011/11/29 PHP
PHP对表单提交特殊字符的过滤和处理方法汇总
2014/02/18 PHP
php eval函数一句话木马代码
2015/05/21 PHP
PHP提取字符串中的手机号正则表达式怎么写
2017/07/17 PHP
PHP使用 Pear 进行安装和卸载包的方法详解
2019/07/08 PHP
(推荐一个超好的JS函数库)S.Sams Lifexperience ScriptClassLib
2007/04/29 Javascript
分享10篇优秀的jQuery幻灯片制作教程及应用案例
2011/04/16 Javascript
js 文本滚动效果的实例代码
2013/08/17 Javascript
用html5 js实现点击一个按钮达到浏览器全屏效果
2014/05/28 Javascript
JavaScript 动态加载脚本和样式的方法
2015/04/13 Javascript
JS实现点击按钮控制Div变宽、增高及调整背景色的方法
2015/08/05 Javascript
jQuery中table数据的值拷贝和拆分
2017/03/19 Javascript
Vue学习笔记进阶篇之过渡状态详解
2017/07/14 Javascript
在vue项目中使用element-ui的Upload上传组件的示例
2018/02/08 Javascript
vue render函数动态加载img的src路径操作
2020/10/26 Javascript
[02:32]DOTA2英雄基础教程 美杜莎
2014/01/07 DOTA
python根据开头和结尾字符串获取中间字符串的方法
2015/03/26 Python
CentOS 7 安装python3.7.1的方法及注意事项
2018/11/01 Python
Python提取频域特征知识点浅析
2019/03/04 Python
Python爬虫 bilibili视频弹幕提取过程详解
2019/07/31 Python
python 3.7.4 安装 opencv的教程
2019/10/10 Python
Python内置加密模块用法解析
2019/11/25 Python
python 变量初始化空列表的例子
2019/11/28 Python
python读取hdfs并返回dataframe教程
2020/06/05 Python
Django vue前后端分离整合过程解析
2020/11/20 Python
css3 实现圆形旋转倒计时
2018/02/24 HTML / CSS
AmazeUI底部导航栏与分享按钮的示例代码
2020/08/18 HTML / CSS
网上签名寄语活动留言
2014/01/18 职场文书
村庄环境整治方案
2014/05/15 职场文书
2014年城管工作总结
2014/11/20 职场文书
党员年度个人总结
2015/02/14 职场文书
2015年办公室人员工作总结
2015/05/15 职场文书
班级元旦晚会开幕词
2016/03/04 职场文书
公文格式,规则明细(新手收藏)
2019/07/23 职场文书
Html5新增了哪些功能
2021/04/16 HTML / CSS