我所理解的javascript中函数的作用域和作用域链
http://www.cnblogs.com/zt-blog/p/6654308.html
写在前面
一周木有更新了,今天终于攻克了自行车难关,非常开心,特意来一更~ (那些捂嘴偷笑的人我看到你们了快把嘴闭上我会假装没看见)。
本文内容均基于个人理解,如有不认同,墙裂欢迎留言交流~~~
正文
作用域
简单来说,javascript中有变量和函数的声明/定义,有变量赋值和函数的执行 ,且遵循先声明后执行原则,举个例子:
var a = 1; // 表达式
function func(){ a = a + 1; }; // 函数声明
func(); // 函数执行
上面的代码等同于下面这个:
var a; // 变量声明
function func(){ a = a + 1; }; // 函数声明
a = 1; //执行变量赋值
func(); // 函数执行 --> a=2
理解了先声明后执行原则之后,再来看作用域部分。简单来说,javascript的作用域分两类,一类是最外层作用域,如javascript标签包裹起来的块,或者常见的包含init()的块,如下:
//html文件中 script标签包裹的块
<script>
...
</script> //外部 javascript文件中最外层的块,一般包含init()
function init(){ ... }
...
init()
另一类是当javascript碰到一个function时,这个function内部会形成一个它内部的作用域。如下:
/*相对于函数来说的作用域*/ ...
//这里是函数外部作用域
...
function(){
//这里是函数内部作用域
// ...
}
第一次敲桌子--内部作用域可以访问外部作用域的值,反之行不通!好了,知道了这两类作用域后,再来边举个栗子边梳理作用域这个东西,栗子如下:
var a = 1;
var b;
var c;
function f(){
b = 2;
var d = 3;
console.log(a); //1
console.log(b); //
console.log(d); //3
}
f();
console.log(a); //
console.log(b); //
console.log(c); //undefined
console.log(d); //报错: d is not defined
上面的栗子已经注释给出了结果,看到输入的结果觉得正常么?(我好像问了句废话。。。)我还是按照先声明后执行的原则来看下,首先,从上到下,声明了变量a,b,c,函数f,接着执行了a=1,执行函数f,这里第二次敲桌子啦敲桌子!!-- 执行f的时候发生了什么呢?不记得的翻上去看下,首次敲桌时说过了函数内部会形成新的内部的作用域。我们来看下这个作用域,首先声明d,然后执行b=2,d=3,console.log(a),第一次敲桌子的时候说了内部作用域可以访问外部作用域的值,so这里a输入为1,接下来b和d都在函数内部赋过值了,所以console.log(b)和console.log(d)分别输出2和3。至此,f已经执行完了(下划线这部分),继续,console.log(a)这里a也已经赋过值会输出1,console.log(b) -- 第三次敲桌子啦!!!--b声明在外部作用域,赋值在f内部作用域,那么这个赋值的结果在外部作用域还生效么?答案显而易见,生效的,输出2(因为外部声明了,这个变量就一直存在,其他地方的赋值对其均有效)。再然后console.log(c) -- 第四次敲桌子!!!!c只是声明了而已,并没有赋值,因此输出undefined。最后console.log(d) -- 第五次敲桌子!!!!!d为啥会报错呢?回头看首次敲桌时是怎么说的,“反之行不通”,即:函数外部不能访问其内部定义的变量!再回来看d,d只是在f内部定义了,而外部并没有权限访问它,所以这次报错d is not defined...
/*注意区分undefined 和 d is not defined,一个未赋值,一个根本未声明过。*/
作用域链
看上面栗子中的5,7,8行,分别用到了a和b两个变量,这两个变量在f中声明了么?并没有,那为什么还能输出正确的值呢?作用域链就在这时候登场了。f中找不到相应的变量时,向上(外部)一层一层寻找直到最外层,找到则引用,找不到则报错 -- 就是这么简单!
思考题
var a = 10;
var b = 5;
function f(){
console.log(a);
var a = 20;
console.log(a);
var d = 30;
var ff = function(){a++; b++; d++; console.log(a); console.log(b); console.log(d);}
return ff;
} var c = f();
c();
f()();
c();
好好想想这个思考题,注意return的部分,三思而后F12哦~~~
本文完。
我所理解的javascript中函数的作用域和作用域链的更多相关文章
- Javascript中函数的四种调用方式
一.Javascript中函数的几个基本知识点: 1.函数的名字只是一个指向函数的指针,所以即使在不同的执行环境,即不同对象调用这个函数,这个函数指向的仍然是同一个函数. 2.函数中有两个特殊的内部属 ...
- javascript中不存在块级作用域,所以要小心使用在块级作用域中的函数声明所带来的作用域混乱.
在javascript中函数的作用域是一个非常重要的概念. javascript中是没有块级作用域,但是有函数作用域的概念. 我们在开发的过程中,经常会遇到这样的问题, 某个函数我暂时不需要,不想声明 ...
- JavaScript 中函数节流和函数去抖的讲解
JavaScript 中函数节流和函数去抖的讲解 我们都知道频繁触发执行一段js逻辑代码对性能会有很大的影响,尤其是在做一些效果实现方面,或者逻辑中需要进行后端请求,更是会导致卡顿,效果失效等结果,所 ...
- JavaScript中函数是不能重载原因
以前有一次写JS插件的时候,由于后台写习惯了,妄想在JS中写重载函数,可惜不能成功,原因花了一点时间记了下来 首先要理解重载的含义:函数返回值不同或者形式参数个数不同但函数名相同的函数 JavasSc ...
- JavaScript中函数作为另一个函数的参数的时候它存在于哪个作用域
一直对函数作为参数被传递进另外一个函数理解的不是很清除.先看下这段代码吧: function test(fn){ var bar = 1; fn(); } var bar = 99; test(fun ...
- JavaScript中函数函数的定义与变量的声明<基础知识一>
1.JavaScript中函数的三种构造方式 a.function createFun(){ } b.var createFun=function (){ } c.var createFun=new ...
- JavaScript中函数的形参和实参的实现原理剖析
我们都知道JS里面参数的传递是可以不一样的,比如我们有一个函数: <script type="text/javascript"> function one(a,b,c) ...
- JavaScript中函数的调用
JavaScript中函数的调用 制作人:全心全意 在JavaScript中,函数定义后并不会自动执行,要执行一个函数需要在特定的位置调用该函数,调用函数需要创建调用语句,调用语句包含函数名称和参数. ...
- JavaScript中函数的定义
JavaScript中函数的定义 制作人:全心全意 在JavaScript中,函数是由关键字function.函数名加一组参数以及置于大括号中需要执行的一段代码定义的.定义函数的基本语法格式如下: f ...
随机推荐
- Java Properties类源码分析
一.Properties类介绍 java.util.Properties继承自java.util.Hashtable,从jdk1.1版本开始,Properties的实现基本上就没有什么大的变动.从ht ...
- 每天一个Linux命令(03)--pwd
linux 中用 pwd命令来查看“当前工作目录”的完整路径.简单地说,每当你在终端进行操作时,你都会有一个当前工作目录. 在不太确定当前位置时,就会使用pwd来判断当前目录在文件系统内的确切位置. ...
- 信号处理——傅里叶变换(FT-DTFT-DFT)
作者:桂. 时间:2017-01-17 23:41:13 链接:http://www.cnblogs.com/xingshansi/articles/6294111.html 声明:转载请注明出处, ...
- ERP实施规范化及示例——邮件沟通
上门服务前 上门服务计划,要详细,提前发给客户,反复确定双方的行程 上门服务所需的常规文档(培训SOP,培训记录) 项目组内反复确认本次上门要完成的事项 …… 上门服务中 先跟老板沟通项目进展,本次上 ...
- 数字化工厂解决方案——OA办公自动化与ERP
移动办公APP/即时通讯 通过集成手机应用,将移动办公引入到企业信息化管理中,能随时随地的完成审批.查询.警报.知会.公告发布.KPI统计和信息推送.系统已经支持苹果系统.安卓系统和微软WP8系统.企 ...
- 走进 Redis 的世界
NoSQL(Not Only SQL) 在现今已经应用非常普遍了,尤其是 Redis 和 MongoDB.我们现在来说说 Redis. 前世 Redis 是一个意大利人 Salvatore Sanfi ...
- Ubuntu 开机启动是出现 grub rescue 解决办法
最近想在Ubuntu的基础上,再在硬盘的一个分区安装Windows,其中有次不小心,在安装windows的时候,删除了一个分区,造成下次启动Ubuntu系统出现 grub rescue 下面是我的修复 ...
- OnsenUI和AngularJS配合搭建混合应用的基本步骤
混合开发的热潮已经掀起,实现混合开发的方式很多.今天给大家介绍一个实现混合开发的基本方法-OnsenUI和AngularJS配合. OnsenUI是一个可以实现混合开发的前端框架,包含了很多前端设计中 ...
- 从客户端中检测到有潜在危险的 Request.Form或Requst.String的值。
在ASP中客户端请求服务时会出现"从客户端中检测到有潜在危险的 Request.Form或Requst.QueryString的值.",原因是在web.config配置文件中存在这 ...
- Winform自定义控件在界面上拖动、滚动鼠标。。会闪烁的解决方法
环境说明: 项目中有一个基类窗体BaseForm,有一个自定义控件TextBoxBase,两个控件都做了一些独特常规的封装和重写,在TextBoxBase中有一点重绘的下划线,发现在窗体运行之后, ...
cnzt