变量是一个和数值相关的名字。我们说变量“存储”了或“包含”了那个值。
变量的类型
javascript和java和C这样的语言之间存在一个重要的差别,那就是javascript是非类型的。这意味着javascript的变量可以存放任何类型的值。i=10;i="ten";是合法的。
变量的声明
在javascript程序中,在使用一个变量之前,必须声明它。
var i;
var sum;
也可以使用一个var声明多个变量:
var i,sum;
而且还可以将变量声明和变量初始化绑定一起:
var i=0,j=0,k=0;
var message ="hello";
如果没有用var语句给一个变量指定初始值,那么虽然这个变量被声明了,但是在给它存入一个值之前,它的初始值就是undefined。
重复的声明和遗漏的声明
使用var语句多次声明同一个变量不仅是合法,而且也不会造成任何错误。如果重复的声明有一个初始值,那么它担当的不过是一个赋值语句的角色。
如果尝试读一个没被声明的值,javascript会生成一个错误。如果尝试给一个未用var声明的变量赋值,javascript会隐试声明该变量。但是要注意,隐式声明的变量总是被创建为全局变量,即使该变量只在一个函数体内使用。
变量的作用域
一个变量的作用域是程序中定义这个变量的区域。全局变量的作用域是全局性的,即javascript代码中,它处处都有意义。而在函数之内声明的变量,就只在函数体内部有意义。它们是局部变量,作用域是局部性的。函数参数也是局部变量,它们只在函数体内有意义。函数体内,局部变量的优先级比同名的全局变量高。
var scope = "123"; function checkscope() { var scope = "456"; document.write(scope); } //输出456
虽然全局作用域中编写代码时可以不用var语句,但是在声明局部变量时,一定要使用var语句。
没有块级的作用域
javascript没块级作用域,函数中声明的所有变量,无论在哪里声明的,在整个函数中它们都是有意义的。
function test() { var i = 0; if (true) { var j = 0; for (var k = 0; k < 10; k++) { document.write(k); } document.write(k); } document.write(j); } //输出0123456789100
var scope ="123" function test() { alert(scope); //输出的是undefined var scope = "456"; alert(scope); //输出的456 }
为什么第一次用会出现undefined(alert的scope是局部类型的,虽然还没声明!)。因为声明局部变量的var语句还没有执行。
未定义的变量和未赋值的变量
一个变量从没被声明过的,尝试读取这种未声明的变量会引起运行时的错误。(未被声明的的变量)。一个变量被声明了,但没有被赋值的变量,尝试读取这种未赋值的变量,将会得到一个默认值,即undefined.
基本类型和引用类型
数值、布尔值、null、undefined属于基本类型。对象、数组和函数属于引用类型。基本类型在内存中有固定的大小。但引用类型则不同。如对象可以具有任意的长度,它并没有固定的大小。数组和函数也是这样。由于这些
类型没有固定大小,所以不能把它们的值直接存放在相关八字节的内存中,但可以存储相关的指针或内存地址,告诉变量在哪里可以找到这个值。
function f() { var a = [1, 2, 3]; var b = a; a[0] = 58; alert(b);//输出为58,2,3而不是1,2,3因为b是引用类型,a和b都指向同一个地方 }
string类型是一个特例。因为它具有可变的大小,所以不能存储在固定大小的变量中。但string类型做赋值时的效果却和基本类型一样!
垃圾收集
javascript和C 、C++不同。javascript的解析器可以检测到何时程序不再使用一个对象了。当它确定了一个对象时无用时,它就会把这个对象的内存释放掉。垃圾收集时自动执行的,对程序员时不可见的。
作为属性的变量
javascript的变量和对象的属性有很多的相似点。例如,变量i和对象o的属性i,是没有根本的区别的。
全局对象
当javascript的解析器开始运行时,它首先要做的事情之一就是执行任何的javascript代码之前,创建一个全局对象(global object)。这个对象的属性就是javascript程序的全局变量。当声明一个javascript
的全局变量时,实际上座的是定义了那个全局变量的一个属性。此外,javascript的解析器还会用预定义的值和函数来初始化全局对象的许多属性。例如属性Infinity、parseInt和Math。在程序的顶层代码中(例如,不属于函数
javascript代码),可以使用javascript的关键字this来引用这个全局对象。在客户端javascript中,window对象代表浏览器窗口,它包含在该窗口中的所有javascript代码的全局对象。这个全局window对象具有自我引用的
window属性。
局部变量:调用对象
如果全局变量是特殊的全局对象的属性,那么局部变量又是什么呢?它们也是一个对象的属性,这个对象被称为调用对象。虽然调用的声明周期比全局对象的短,但是它们的用途是相同的。在执行一个函数时,函数和局部变量是作为对用属性而存储的。用一个完全独立的对象来存储局部变量使javascript可以防止局部变量覆盖同名的全局变量。