JavaScript学习笔记

关键字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 = {}
11.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 = {}
11.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出来。