浅析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 string 转 int 注意的问题小结
Aug 15 Javascript
JavaScript函数获取事件源的小例子
May 14 Javascript
JavaScript中this的9种应用场景及三种复合应用场景
Sep 12 Javascript
javascript获取网页各种高宽及位置的方法总结
Jul 27 Javascript
详解React native全局变量的使用(跨组件的通信)
Sep 07 Javascript
Vue-cli 使用json server在本地模拟请求数据的示例代码
Nov 02 Javascript
JS实现获取汉字首字母拼音、全拼音及混拼音的方法
Nov 14 Javascript
详解layui弹窗父子窗口之间传参数的方法
Jan 16 Javascript
node.js利用socket.io实现多人在线匹配联机五子棋
May 31 Javascript
vue slots 组件的组合/分发实例
Sep 06 Javascript
vue动态设置img的src路径实例
Sep 18 Javascript
深入学习Vue nextTick的用法及原理
Oct 08 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
MYSQL 小技巧 -- LAST_INSERT_ID
2009/11/24 PHP
PHP中防止SQL注入实现代码
2011/02/19 PHP
图解找出PHP配置文件php.ini的路径的方法
2014/08/20 PHP
PHP利用imagick生成组合缩略图
2016/02/19 PHP
解决thinkPHP 5 nginx 部署时,只跳转首页的问题
2019/10/16 PHP
js用图作提交按钮或超连接
2008/03/26 Javascript
关于JQuery($.load)事件的用法和分析
2013/04/09 Javascript
nodeType属性返回被选节点的节点类型介绍
2013/11/22 Javascript
解决JQeury显示内容没有边距内容紧挨着浏览器边线
2013/12/20 Javascript
jquery.ajax的url中传递中文乱码问题的解决方法
2014/02/07 Javascript
JavaScript知识点总结之如何提高性能
2016/01/15 Javascript
jquery $.trim()去除字符串空格的实现方法【附图例】
2016/03/30 Javascript
JS实现图片高斯模糊切换效果的焦点图实例
2017/01/21 Javascript
js 数据存储和DOM编程
2017/02/09 Javascript
解决npm安装Electron缓慢网络超时导致失败的问题
2018/02/06 Javascript
vue中使用element-ui进行表单验证的实例代码
2018/06/22 Javascript
基于vue.js中关于下拉框的值默认及绑定问题
2018/08/22 Javascript
vue实现购物车结算功能
2020/06/18 Javascript
javascript递归函数定义和用法示例分析
2020/07/22 Javascript
python抓取文件夹的所有文件
2018/02/27 Python
使用pandas中的DataFrame数据绘制柱状图的方法
2018/04/10 Python
利用pandas读取中文数据集的方法
2018/07/25 Python
Python用5行代码写一个自定义简单二维码
2018/10/21 Python
基于树莓派的语音对话机器人
2019/06/17 Python
分享PyCharm的几个使用技巧
2019/11/10 Python
wxPython之wx.DC绘制形状
2019/11/19 Python
HTML5 Blob对象的具体使用
2020/05/22 HTML / CSS
英国排名第一的宠物店:PetPlanet
2020/02/02 全球购物
创业资金计划书
2014/02/06 职场文书
《望庐山瀑布》教学反思
2014/04/22 职场文书
公司活动总结范文
2014/07/01 职场文书
在职员工证明书
2014/09/19 职场文书
2014年发展党员工作总结
2014/11/12 职场文书
清洁工个人工作总结
2015/03/05 职场文书
中学生国庆节演讲稿2015
2015/07/30 职场文书
珍爱生命主题班会
2015/08/13 职场文书