词法分析/作用域

1.js变量的查找

js中函数嵌套是十分普遍的
对变量是如何寻找的?------->从内部向外部寻找
首先在函数内寻找
找不到就在外层找
直到全局(window)区域

源码例子

var c=5;
function t1(){
    var d=6;
    function t2(){
        var e=7;
        //var d=3; 去掉注释观察结果的变化
        alert(c+d+e);
    }
    t2();
}

t1();//分别得到15,18

2.声明变量var的作用


alert(window.d);//undefine
alert(window.e);//undefine
function t(){
    d=5;
    var e=6;
}
t();

alert(window.d);//5  没有加var就是仅仅是赋值操作,寻找t域内的函数,没有找到,继续寻找。。。。>window-->window.d=5
alert(window.e);//undefine


//var 是在函数运行的上下文中,申明一个变量 如果不加var,则是一个赋值操作,不要狭隘理解为创造了一个全局变量
function t1(){
    var d;
    function t2(){
        d=5;
        e=6;
    }
    t2();
}
t1();
console.log(d);//d is not defined错误  
console.log(e);//6
console.log(window.d);//undefine

//注意:以window.xxx引用全局变量,寻找不到作为某个属性不存在,返回 undefined 直接以xxx引用某变量寻找不到则是报 xxx is not define 错误

例题

var str1='global';
function t1(){
    console.log(str1);//返回global
    console.log(str2);//报str2 is not defined
    str2='local';//做了window.str2='local'这样一个操作
}
t1();
//在t1寻找str1---没有,在window上寻找str1---有  打印global
//在t1寻找str2---没有,在window上寻找str2---没有,报str2 is not defined
//(实际上出错还没有执行到这一些)才把全局的str2的变量赋值上去
var str1='global';
function t1(){
    console.log(str1);//返回global
    console.log(str2);//返回undefined
    var str2='local';
}
t1();

js代码自上而下执行
但是js代码在整体运行分为 词法分析期 ,运行期
自上而下执行之前,先有个词法分析过程
------------------------------------------------例如---------------------------------------------------------------
第一步:先分析t1函数
分析出t1内有str2局部变量,注意此时代码未运行str2未赋值,所以str2的值是undefined
第二步:执行t1函数
console.log(str1);//返回global
console.log(str2);//返回undefined
str2='local'//此时str2的值为local

3.词法分析

词法分析
第一步:分析参数
第二部:分析变量声明
第三步:分析函数声明

一个函数能使用的全局变量,就是按照上面的三个步骤分析而来的

具体步骤:
0:函数运行前的瞬间,生成active object(活动对象),下面简称为ao
1:函数声明的参数形成ao的属性,参数的值就是属性的值,接收实参,形成ao相应属性的值
2:分析变量的声明
如果ao没有有age属性则添加为ao属性,值全是undefined
如果ao上已经有age属性,则不做任何影响
3:分析函数申明,如function foo(){}
把函数赋给ao.foo属性
注:如果此时foo属性已经存在,则被无情覆盖
实例1

function t(age){
    alert(age);
}
t(5);//5
t();//undefined

/*
词法分析过程
ao{age:undefined}
运行过程:
t(5)-->ao.age=5;alert(ao.age);//5

t()--->ao.age没有得到赋值还是undefined
*/

实例2

function t2(age){
    var age=99;
    alert(age);
}
t2(5);
/*
分析过程:
0:形成ao={}
1:分析形参ao={age:undefined}
   接收形参ao={age:5}
2:分析var age,发现ao已经有age属性,不做任何影响

执行过程:
ao.age=99;
alert(age);
*/

实例3

function t3(greet){
    var greet='hello';//试着变成var greet试一下
    alert(greet);
    function greet(){

    }
    alert(greet);
}
t3(null);//hello    hello
/*
词法分析过程:
0:ao={}
1:分析参数ao={greet:undefined}
   接收形参ao={greet:null}
2:分析greet变量声明,ao已经有greet 属性,因此不做任何影响
3:分析greet函数声明,ao.greet=function(){},被覆盖为函数

执行过程:
greet='hello';
alert(greet);//---------->hello
alert(greet);//---------->hello
*/

实例4

function a(b){
    alert(b);
    function b(){
        alert(b);
    }
    b();
}
a(1);
/*
分析:

0:ao={}
1:分析参数ao= {b:undefined}
  接收参数ao={b:1}
2:分析var 声明,此函数没有var
3:分析函数声明,ao={b:function{alert(b);}}

执行:
alert(b);

*/

实例6

function a(b){
    alert(b);
    b=function(){
        alert(b);
    }
    b();
}
a(1);
/*
分析:
0:生成ao对象ao={}
1:分析参数ao={b:undefined}-->{b:1}
2:分析var声明--->没有
3:分析函数声明,--->没有,b=function(){}是一个赋值过程,是函数表达式返回值赋给变量b,这是一个赋值过程,要在执行过程中生效

执行:
alert(b);//1
b=function(){
    alert(b);
}
b();//function

*/

4.函数声明和函数表达式

js被称为披着c外衣的lisp语言,
lisp是一种强大的函数式语言
函数的地位比较高,函数可以作为参数来传递,可以复制给变量

function t1(){}//t1是函数声明
t2=function(){}//t2是函数赋值过程,值是右侧表达式的返回结果

//function(){}在js看来就是3+2一样,是一个表达式,返回一个结果
//因此,t1 t2 在词法分析过程有着明显的区别,前者在词法分析阶段就发挥作用,后者在运行阶段才发挥作用


(function (window.undefined){})(window);
//这是jquery的最外层代码
(function(window.undefined))//内层表达式,返回值是函数,包在小括号内,当成表达式来使用
(window)//立即调用,并传一个window

//而内层函数没有起名字,叫匿名函数,这种方法好处: 立即执行不污染全局,称为 立即执行匿名函数表达式

//为什么传window不传undefined?
//传window是为了速度,加快内部查找全局变量的速度,直接把window以参数形式传进来,这样window就在jquery内部的ao上

    function(){
        function(){
            function(){
                function{
                    function(){
                        document.getElementById()//这个document会将作用域层层上找,直到最外层
                    }
                }
            }
        }
    }

//不传undefined是为了安全,在ie低版本张,undefined竟然可以重新赋值,如undefined=3
//声明undefined局部变量(名字是undefined而已),同时又不传参,值自热是undefined,阻止了外界对undefined的污染

5.作用域链

JavaScript 开发进阶:理解 JavaScript 作用域和作用域链
Js作用域与作用域链详解

你可能感兴趣的:(词法分析/作用域)