http://www.cnblogs.com/zt-blog/p/6654308.html
写在前面
一周木有更新了,今天终于攻克了自行车难关,非常开心,特意来一更~ (那些捂嘴偷笑的人我看到你们了快把嘴闭上我会假装没看见)。
本文内容均基于个人理解,如有不认同,墙裂欢迎留言交流~~~
正文
作用域
简单来说,javascript 中有变量和函数的声明 / 定义,有变量赋值和函数的执行 , 且遵循先声明后执行原则,举个例子:
- 1
- var a = 1; // 表达式
- 2 3
- function func() {
- a = a + 1;
- }; // 函数声明
- 4 5 func(); // 函数执行
上面的代码等同于下面这个:
- 1
- var a; // 变量声明
- 2 3
- function func() {
- a = a + 1;
- }; // 函数声明
- 4 5 a = 1; //执行变量赋值
- 6 func(); // 函数执行 --> a=2
另一类是当 javascript 碰到一个 function 时,这个 function 内部会形成一个它内部的作用域。如下:
- /*相对于函数来说的作用域*/
- ...
- //这里是函数外部作用域
- ...
- function(){
- //这里是函数内部作用域
- // ...
- }
第一次敲桌子 -- 内部作用域可以访问外部作用域的值,反之行不通!好了,知道了这两类作用域后,再来边举个栗子边梳理作用域这个东西,栗子如下:
- 1
- var a = 1;
- 2
- var b;
- 3
- var c;
- 4
- function f() {
- 5 b = 2;
- 6
- var d = 3;
- 7 console.log(a); //1
- 8 console.log(b); //2
- 9 console.log(d); //3
- 10
- }
- 11 f();
- 12 console.log(a); //1
- 13 console.log(b); //2
- 14 console.log(c); //undefined
- 15 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...
作用域链
看上面栗子中的 5,7,8 行,分别用到了 a 和 b 两个变量,这两个变量在 f 中声明了么?并没有,那为什么还能输出正确的值呢?作用域链就在这时候登场了。f 中找不到相应的变量时,向上 (外部) 一层一层寻找直到最外层,找到则引用,找不到则报错 -- 就是这么简单!
思考题
- 1
- var a = 10;
- 2
- var b = 5;
- 3
- function f() {
- 4 console.log(a);
- 5
- var a = 20;
- 6 console.log(a);
- 7
- var d = 30;
- 8
- var ff = function() {
- a++;
- b++;
- d++;
- console.log(a);
- console.log(b);
- console.log(d);
- }
- 9
- return ff;
- 10
- }
- 11 12
- var c = f();
- 13 c();
- 14 f()();
- 15 c();
好好想想这个思考题,注意 return 的部分,三思而后 F12 哦~~~
本文完。
来源: http://www.cnblogs.com/zt-blog/p/6654308.html