变量的类型和做用域

1、变量的类型
JS是一种无类型、弱检测的语言。它对变量的定义并不须要声明变量类型,咱们只要经过赋值的形式,能够将各类类型的数据赋值给同一个变量。例如:
i=100;//Number类型
i="variable";//String类型
i={x:4};//Object类型
i=[1,2,3];//Array类型
2、变量的声明
JS中变量申明分显式申明(局部变量)和隐式申明(全局变量)。
var i=100;//显式申明
i=100;//隐式申明

在函数中使用var关键字进行显式申明的变量是作为局部变量,而没有用var关键字,使用直接赋值方式声明的是全局变量。
注意:当咱们使用或访问一个没有声明的变量时,JS会报错。而当咱们给一个没有声明的变量赋值时,JS不会报错,相反它会认为咱们是要隐式申明一个全局变量。
3、全局变量和局部变量
当JS解析器执行时,首先就会在执行环境里构建一个全局对象,咱们定义的全局属性就是作为该对象的属性读取,在顶层代码中咱们使用this关键字和window对象均可以访问到它。
而函数体中的局部变量只在函数执行时生成的调用对象中存在,函数执行完毕时局部变量即刻销毁。
所以在程序设计中咱们须要考虑如何合理声明变量,这样既减少了没必要要的内存开销,同时能很大程度地避免变量重复定义而覆盖先前定义的变量所形成的Debug麻烦。
4、变量做用域
JS中变量的做用域,一个很大的特征就是JS变量没有块级做用域,函数中的变量在整个函数都中有效,运行下面代码1:
function outPut(s){
    document.writeln(s)
}
var i=0;//全局变量
//定义外部函数
function outer(){
    outPut(i); //访问全局变量 0
    //定义一个内部函数
    function inner(){
        var i = 1;//显示申明 定义局部变量
//        i=1; //若是用隐式申明 那么就覆盖了全局变量i
        outPut(i); //访问局部变量 1
    }
    inner();
    outPut(i); //访问全局变量 0
}
outer();
输出结果为0 1 0,从上面就能够证实JS若是用var在函数体中声明变量,那么此变量在且只在该函数体内有效,函数运行结束时,局部变量即刻销毁了。
运行下面代码2:
function outPut(s){
    document.writeln(s)
}
var i=0;//全局变量
//定义外部函数
function outer(){
    outPut(i); //访问全局变量 0
    //定义一个内部函数
    function inner(){
        outPut(i); //undefined
        var i = 1;//显示申明 定义局部变量
        outPut(i); //访问局部变量 1
    }
    inner();
    outPut(i); //访问全局变量 0
}
outer();
输出结果是0 undefined 1 0,由于JS函数体中声明的局部变量在整个函数中都有效,所以在上面代码中var i = 1 ;在inner函数中都有效,实际上显式声明的变量i是在预编译时就已经编译到调用对象中了,不一样于隐式声明变量在解释时才被定义为全局变量,只是在调用outPut(i)时,尚未将它初始化变量,此时的局部变量i是未赋值变量,而不是未定义变量,所以输出了undefined。上面的代码等效于下面代码:
function inner(){
    var i; //定义但不赋值
    outPut(i); //undefined
    i=1;
    outPut(i); //1
}
为了不上面的这类问题,所以在函数开始位置集中作函数声明是一个极力推荐的作法。
5、基本类型和引用类型
JS在变量申明时并不须要声明变量的存储空间。变量中所存储的数据能够分为两类:基本类型和引用类型。其中数值、布尔值、null和undefined属于基本类型,对象、数组和函数属于引用类型。
基本类型在内存中具备固定的内存大小。例如:数值型在内存中占有八个字节,布尔值只占有一个字节。对于引用型数据,他们能够具备任意长度,所以他们的内存大小是不定的,所以变量中存储的其实是对此数据的引用,一般是内存地址或者指针,经过它们咱们能够找到这个数据。
引用类型和基本类型在使用行为上也有不一样之处:
//定义一个输出函数
function outPut(s){
    document.writeln(s)
}
var a = 3;
var b = a;
outPut(b);//3
a = 4;
outPut(a);//4
outPut(b);//3
对基本类型b进行赋值时,其实是又开辟了一块内存空间,所以改变变量a的值对变量b没有任何影响。
//定义一个输出函数
function outPut(s){
    document.writeln(s)
}
var a_array = [1,2,3];
var b_array = a_array;
outPut(b_array); //1,2,3
a_array[3] = 4;
outPut(b_array);//1,2,3,4
上面是对引用类型的变量赋值,实际上他们传递的是对内存地址的引用,所以对a_array和b_array的存取,实际上都是操做的同一块内存区域。若是但愿从新分配内存空间存储引用型变量,那么我就须要使用克隆方法或者自定义方法来复制引用变量的数据。数组

相关文章
相关标签/搜索