码迷,mamicode.com
首页 > 编程语言 > 详细

javascript 作用域

时间:2015-06-16 18:30:35      阅读:104      评论:0      收藏:0      [点我收藏+]

标签:

作用域:可以理解为在一定范围内对数据进行读、写操作
域:空间、范围、区域...
作用:读、写
浏览器内部,可以暂时把专门用来读取JS的那部分叫做“js解析器”,

“js解析器”工作流程:
“js解析器”在读取代码的时候,会先找一些东西存在仓库里,然后再去逐行解读代码
第一步:找一些东西-->JS的预解析:有变量就是未定义,有函数就是函数的整体
关键字:var 、 function 、参数
变量时:a = 未定义
所有的变量,在正式运行代码前,都提前赋了一个值:未定义
函数时:fn1 = function fn1(){alert(2);}
所有的函数,在正式运行代码前,读取都是整个函数整体
注意:如果函数和变量重名时:只留函数;
函数和函数重名时:只留后者
第二步:逐行解读代码
顺序:从上到下,从左往右-->每读取一行代码就会到“JS的预解析”的那个仓库里看下有没有那个数据
留意表达式: = + - * / ++ -- 参数 ! 等所有能改变值的表达式,遇到表达式的时候会去修改预解析仓库里的值
留意函数调用:如果遇到函数调用,就在函数体内开了一个新的作用域,以当前函数为单位来进行预解析及逐行解读代码,如果在预解析的过程中,发现函数体内既没有var又没有function的时候,就会向它上一级元素(父元素)里去找想要的东西。(作用域链)

例如:
alert(a); // function a(){alert(4);} ----> 结果为仓库里的值
var a=1; // 此行代码为表达式 --->把仓库的值a由function a(){alert(4);} 改为 1
alert(a); // 1
function a(){
     alert(2);
} //此处为声明函数 ,没有被调用,忽略
alert(a); // 1
var a=3; // 此行代码为表达式 --->把仓库的值a由1改为3
alert(a); // 3
function a(){
    alert(4);
} //此处为声明函数,没有被调用,忽略
alert(a); // 3
alert(typeof a); // number
a(); //报错 :a is not a function --->此时仓库只有值a=3,并未有函数,所以此调用不合法,会报错

分析:
“js解析器”在读取这段代码的时候,会先在代码里找到一些关键字(var、function),把他存到仓库里.
上例中,仓库出现过的值依次为:
1) a = undefined
2) a = function a(){
             alert(2);
          }
3) a = undefined
4) a = function a(){
              alert(4);
          }
但是,解析器在解析代码时,会遵循以下原则:
如果函数和变量重名:只留函数;函数和函数重名:只留后者。
所以,最终仓库里的值为: a = function a(){alert(4);}

完成以上步骤后,解析器开始逐行解读代码,结果见例子注释部分。

例如:
var a = 1; // 仓库里的a由undefined变成1
function fn1(a){
       alert(a); // undefined
       a = 2; // 仓库里的a由undefined变成了2
} //函数声明,忽略
fn1(); // 此处发生函数调用,对fn1开始预解析及逐行解读代码
alert(a); // 1 这里的a是全局变量的,不是fn1里面的a,所以值为1

分析:
预解析:
a = undefined
fn1 = function fn1(a){
    alert(a);
    a = 2;
}
逐行解读代码:执行到fn1()的时候, 发生了函数调用,所以对fn1开始预解析及逐行解读代码,如下:
预解析:
fn1有一个参数a,所以此时a = undefined
逐行解读代码:
function fn1(a){
    alert(a); // undefined
    a = 2; // 仓库里的a由undefined变成了2
}

实际应用:
1)局部变量可以改变全局变量的值。
2)
function fn1(){
    var a ="lily";
}
alert(a); // 报错,外部不可直接访问函数内的变量

想获取函数内部的值:
1)用全局变量去获取函数内的值(作用域链)
var str= "";
function fn1(){
     var a = "lily";
     str = a;
}
fn1();
alert(str); //lily

2) 通过函数调用,(让fn3能弹出出fn2的内容)
function fn2(){
   var a="lily"; //此时仓库里由a=undefined变成a=‘lily‘
   fn3(a); //逐行解读代码的时候找不到关于fn3的,所以会去下边的fn3函数里找
}
fn2(); //发生函数调用,然后对fn2预解析并逐行解读代码,
   function fn3(a){
   alert(a); //lily
}
解析:
首先通过函数调用fn2(),来预解析fn2()函数里的代码,此时a=undefined;解析完毕,开始去逐行解读fn2这个函数.如下:
var a="lily"; 此时a由undefined变成lily,
读到fn3(a)这句代码的时候,在fn2这个函数里找不到相关的东西,所以会去函数外面找,找到了fn3这个函数,通过传参在fn3函数里得到fn2函数a的值。

(根据妙味的课程整理)

javascript 作用域

标签:

原文地址:http://www.cnblogs.com/banmengbanxing/p/4581246.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!