关键字var的作用
var是在函数运行的上下文中,声明一个变量。
如果不加var,则是一个赋值操作,不要狭隘的理解为声明一个全局变量
console.log(window.d); //undefined
console.log(window.e); //undefined
function t(){
d = 5; //d没加var,仅仅是一个赋值操作,寻找t函数域内,没找到,继续寻找——————>window,没找到,执行window.d
var e = 6;
}
t();
console.log(window.d); //5
console.log(window.e); //undefined
// 与上面代码无关系
function t1() {
var d;
function t2(){ d = 5; e = 6;}
t2();
}
t1();
console.log(e); // 6
console.log(d); // d is not defined
console.log(window.d); // undefined
注意:
以window.xxx引用全局变量,寻找不到,作为某个属性不存在,返回undefined
变量定义了,但是没有赋值
以XXX引用某变量,寻找不到,则报xxx is not defined。变量未定义。
变量的生命周期
变量的生命周期: 变量在内存中存放时间的长短.
// 变量分两类: 1.全局变量 2.局部变量
全局变量: 定义在函数外部的变量
局部变量: 定义在函数内部的变量
全局变量:直到页面关闭之前,页面关闭之后被删除.
局部变量:直到函数运行完之前存在,执行完后被删除.
作用域
js里没有块级作用域,有的是函数作用域
在js中函数嵌套是非常普遍的,在函数嵌套中,对变量是如何寻找的?
答:首先在函数内寻找,寻找不到则往外层寻找···直到全局(window)区域。
1.在函数的内部,既可以访问全局变量,也可以访问局部变量
2.在函数的外部,只可以访问全局变量
3.当局部变量与全局变量重名时,以局部变量为准
例如:
var c =5;
function t1(){
var d =6;
function t2(){
// var d =3; //注意去掉注释后的变化
var e =7;
alert(c+d+e);
}
t2();
}
t1();
词法分析
关于,函数运行与变量分析有一个通用的方法,如下:
第一步:先分析参数
第二步:再分析变量声明
第三步:再分析函数声明
一个函数能使用的局部变量,就从上面的三步分析而来。
具体步骤:
0:函数运行前的一瞬间,生成Active Object(活动对象),下称AO
1:1.1函数声明的参数形成AO的属性,值全是undefined
1.2接收实参,形成AO相应属性的值。
2:分析变量声明声明声明,var age;
如果AO上还没有age属性,则添加AO属性,值是undefined
如果AO上已有age属性,则不做任何变化。
3:分析函数声明,如:function foo(){} 则把函数赋给AO.foo属性
注:如果此前有foo属性,则会被无情的覆盖。
案例1:
function t(age){
alert(age);
}
t(3);//3
t();//undefined
词法分析过程:
0:形成AO = {}
1:AO{age:undefined}
运行过程:
t(3)-->AO.age=3; alert(AO.age); //3
t()--->Ao.age没有得到赋值 //undefined
案例2:
function t2(age){
var age = 99;
alert(age);
}
t2();//99
词法分析过程:
0:形成AO = {}
1:1.1分析形参AO{age:undefined}
1.2接收实参AO{age:undefined}
2: 分析变量声明,发现AO上已有age属性,不做任何变化。
执行过程:
AO.age = 99;
alert(age);//99
案例3:
function t3(greet){
var greet='hello';
alert(greet);
function greet(){}
alert(greet);
}
t3(null);//hello hello
词法分析过程:
0:形成AO = {}
1:1.1分析形参 AO = {greet:undefined}
1.2接收实参AO{greet:null}
2: 分析变量声明,发现AO上已有greet属性,不做任何变化。
3:分析函数声明,被无情覆盖,所以AO = {greet:function greet(){}}
执行过程:
greet = 'hello';
alert(greet);
alert(greet);
案例4:
function a(b){
alert(b);
function b(){
alert(b);
}
b();
}
a(1);//两个函数
词法分析:
0:形成AO = {}
1:1.1 分析形参 AO = {b:undefined}
1.2 接收实参 AO = {b:1}
2: 分析变量声明,没有变量声明
3:分析函数声明,之前的AO.b属性全部被无情覆盖,AO = {b:function b(){}}
执行过程:
alert(b);
b(); //由作用域寻找到a函数中的b,即function,然后alert出来。
案例5:
function a(b){
alert(b);
b=function(){
alert(b);
}
b();
}
a(1);// 1 function
词法分析过程:
0:形成AO={}
1: 1.1 分析形参 AO = {b: undefined}
1.2 分析实参 AO = {b:1}
2: 变量声明,无变量声明
3:函数声明,无函数声明
执行过程:
alert(b); // 1
b = function(){alert(b)}
b(); // alert(b),由作用域找到a函数中的b即function,然后alert出来。