我所理解的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 ...
随机推荐
- C# 类型和变量
C# 中的类型有两种:值类型 (value type) 和引用类型 (reference type).值类型的变量直接包含它们的数据,而引用类型的变量存储对它们的数据的引用,后者称为对象.对于引用类型 ...
- window7 32位安装Oracle11g
http://www.cnblogs.com/wangsaiming/p/3573509.html
- block循环饮用解决
在block中使用self会引起循环引用导致无法释放. 解决: __weak typeof(self) weakSelf = self; 例如: NSLog(@"init--> val ...
- MySQL备份说明
第一次发布博客,发现目录居然不会生成,后续慢慢熟悉博客园的设置.回正文--- 1 使用规范 1.1 实例级备份恢复 使用innobackupex,在业务空闲期执行,考虑到IO影响及 FLUSH TAB ...
- 关于zepto在chrome中触发两次的解决方案
复现条件:chrome 55+ 1.zepto tap的实现及double fire的原因 在监听DOM根节点的时候,touchStart后通过XY的坐标偏差,与tapTime的计时判断Tap/Lon ...
- SQL中with(nolock)作用说明
要提升SQL的查询效能,一般来说大家会以建立索引(index)为第一考虑.其实除了index的建立之外,当我们在下SQL Command时,在语法中加一段WITH (NOLOCK)可以改善在线大量查询 ...
- App Store 审核 IPv6 问题
应用提交了N次,每次被拒都是说IPv6的事情,花点功夫把这个事情搞清楚. 苹果审核人员回复的原因都差不多,说在他们的IPv6-Only的环境中测试应用,无法正常请求我们的服务器. 因为我们的域名确实没 ...
- lab1-Junit&Eclemma
Software Testing, Lab 1 March 10. 2016, by 赵国佺(3014218108) 一. environment setup Firstly, I downl ...
- nodejs学习一
总觉得一个前端,不懂得一点后端的服务,弱弱的没有存在感,所以利用现在好好 学学有关nodejs 首先是windows上进行nodejs的全局安装 32 位安装包下载地址 : https://nodej ...
- 多种语言开发Spark-以WordCount为例
Spark是目前最火爆的大数据计算框架,有赶超Hadoop MapReduce的趋势.因此,趁着现在还有大多数人不懂得Spark开发的,赶紧好好学习吧,为了使不同的开发人员能够很好的利用Spark,S ...
cnzt