浅析JavaScript中作用域和作用域链


Posted in Javascript onDecember 06, 2016

学习js,肯定要学习作用域,js作用域和其他的主流语言的作用域还存在很大的区别。

一.js没有块级作用域。

 js没有块级作用域,就像这样:

if(){
 var a = 100; 
console.log(a) //输出100
}
console.log(a) //输出100

 js中像if,for,switch之类的语句,他们包含的代码块里面的变量,在代码块外面也能被读取,所以说,js没有块级作用域。

二.js的全局变量

 js中规定,全局变量都可以看作是window的属性,而且全局变量能够被所有的代码块读取。

var a = 10;
function() {
b = 20; 
 console.log(a); //输出10;
}
console.log(b); //输出20;

 虽然在匿名函数中对a没有定义,但是由于a是全局变量,所以其他任何的代码块都能够读取a的值。在一个复杂的项目中,全局变量如果操作不慎,很有可能带来重大的bug。所以在平时写代码的时候,应该尽量避免使用全局变量!对于一个变量来说,如果没有用var来声明的话,那么会自动认为是全局变量,因此,在书写中,一定不能漏写var。

三.js的局部变量

 js中的全局变量,很容易使代码存在问题,所以我们应该明确区分全局变量和局部变量!局部变量只在他所在的函数内部读取,在函数外部却无法读取这个变量。

function doSomething(){
 var blogName="智轩资本";
 function innerSay(){
  alert(blogName);
 }
 innerSay();
}
alert(blogName); //undefined
innerSay(); //undefined

四.js的作用域链问题

 由于js存在全局变量和局部变量,在调用一个变量是,会对他的作用域链进行查找,如果函数内部定义了这个变量,那么取该变量的值,如果没有,那么向上一层查找,如果找到了,就获取这个值,如果还没找到,继续往上层查找,直到找到位置,如果找到最后也没找到,那么该变量的值为undefined。

 先看一个例子:

var myName = '智轩资本';
function scoap() {
  console.log(myName);

var myName = "zhixuan";


console.log(myName);


console.log(age);
 } 
scoap();

先分析一下这个例子,scoap()将调用这个函数,第一个console.log(name),会对name的值进行原型链查找,首先看函数scoap内部是否进行了定义,发现在函数内部对name进行了定义,那么第一个console.log(name)将不再往上层查找!那么第一个console.log(name)的值是不是就是“zhixuan”了呢?no!no!no!由于第一个console.log(name)时,对name还没有赋值,所以,第一个console.log(name)为undefined,第二个console.log(name)为“zhixuan”!

再看一个例子:

var a = 10;
function zhixuan() {
 console.log(a);
}
function ziben() {
 var a = 20;
 zhixuan();
}
ziben();

这次console.log(a)的值为多少呢?首先执行ziben()函数,里面定义了a为20,再执行zhixuan()函数,要求输出a的值,由于作用域在函数定义的那一瞬间就决定了,所以,zhixuan()函数会向上查找到a的全局变量,即var a=10,而不是演着ziben()里的作用域查找!所以console.log(a)为10.

当然,我的这些理解比较浅,如果想要继续深入,推荐阅读:https://3water.com/article/57393.htm

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,同时也希望多多支持三水点靠木!

Javascript 相关文章推荐
js原生态函数中使用jQuery中的 $(this)无效的解决方法
May 25 Javascript
JS+CSS实现自适应选项卡宽度的圆角滑动门效果
Sep 15 Javascript
Bootstrap中CSS的使用方法
Feb 17 Javascript
JavaScript & jQuery完美判断图片是否加载完毕
Jan 08 Javascript
JS实现二叉查找树的建立以及一些遍历方法实现
Apr 17 Javascript
js实现股票实时刷新数据案例
May 14 Javascript
详解CommonJS和ES6模块循环加载处理的区别
Dec 26 Javascript
详解puppeteer使用代理
Dec 27 Javascript
详解iview的checkbox多选框全选时校验问题
Jun 10 Javascript
微信小程序云开发获取文件夹下所有文件(推荐)
Nov 14 Javascript
vue+canvas实现拼图小游戏
Sep 18 Javascript
JS前端可视化canvas动画原理及其推导实现
Aug 05 Javascript
利用JS轻松实现获取表单数据
Dec 06 #Javascript
手机移动端实现 jquery和HTML5 Canvas的幸运大奖盘特效
Dec 06 #Javascript
Javascript highcharts 饼图显示数量和百分比实例代码
Dec 06 #Javascript
jQuery EasyUI 获取tabs的实例解析
Dec 06 #Javascript
如何防止INPUT按回车自动提交表单FORM
Dec 06 #Javascript
详解ECharts使用心得总结
Dec 06 #Javascript
jQuery实现删除li节点的方法
Dec 06 #Javascript
You might like
从零开始 教你如何搭建Discuz!4.1论坛
2006/07/07 PHP
PHP中基本符号及使用方法
2010/03/23 PHP
Ajax PHP JavaScript MySQL实现简易无刷新在线聊天室
2016/08/17 PHP
浅谈PHP中的错误处理和异常处理
2017/02/04 PHP
从阿里妈妈发现的几个不错的表单验证函数
2007/09/21 Javascript
Ext 表单布局实例代码
2009/04/30 Javascript
javascript 定义新对象方法
2010/02/20 Javascript
js二级地域选择的实现方法
2013/06/17 Javascript
EXT中单击button按钮grid添加一行(光标位置可设置)的实例代码
2016/06/02 Javascript
AngularJS模块详解及示例代码
2016/08/17 Javascript
Javascript日期格式化format函数的使用方法
2016/08/30 Javascript
js案例之鼠标跟随jquery版(实例讲解)
2017/07/21 jQuery
AngularJS 打开新的标签页实现代码
2017/09/07 Javascript
Vue前后端不同端口的实现方法
2018/09/19 Javascript
移动端H5页面返回并刷新页面(BFcache)的方法
2018/11/06 Javascript
Vue实现的父组件向子组件传值功能示例
2019/01/19 Javascript
微信小程序去除左上角返回键的实现方法
2020/03/06 Javascript
JavaScript数组排序功能简单实现
2020/05/14 Javascript
JavaScript实现瀑布流布局的3种方式
2020/12/27 Javascript
[03:47]2015国际邀请赛第三日现场精彩回顾
2015/08/08 DOTA
详解Python打包分发工具setuptools
2019/08/05 Python
使用PyQt5实现图片查看器的示例代码
2020/04/21 Python
Python urllib2运行过程原理解析
2020/06/04 Python
Python利用socket模块开发简单的端口扫描工具的实现
2021/01/27 Python
Canvas 文本填充线性渐变的使用详解
2020/06/22 HTML / CSS
介绍一下SQL注入攻击的种类和防范手段
2012/02/18 面试题
时尚休闲吧创业计划书
2014/01/25 职场文书
支部鉴定材料
2014/06/02 职场文书
2014年学生会工作总结范文
2014/11/07 职场文书
婚庆开业庆典主持词
2015/06/30 职场文书
运动会广播稿50字
2015/08/19 职场文书
PHP新手指南
2021/04/01 PHP
SpringBoot SpringEL表达式的使用
2021/07/25 Java/Android
Vue自定义铃声提示音组件的实现
2022/01/22 Vue.js
Python实现文字pdf转换图片pdf效果
2022/04/03 Python
Python循环之while无限迭代
2022/04/30 Python