变量声明: 使用var关键字声明,若是使用没有声明的变量,则JS会自动声明此变量根据变量做用域。若是变量只声明为赋值,则此时值是undefined。重复声明变量,在JS不会报错,会依据最后一次的声明来处理变量。 变量做用域: 一个变量的做用域是,程序代码定义这个变量的区域,全局变量在程序代码内任何地方均可以访问。 包括在{}函数,对象内的变量(属性)成为局部变量。 在函数体内定义的变量成为局部变量,做用域也是局部,函数参数也是局部变量。 他们只在函数体内有意义。 在函数体内,局部变量优先于全局变量,也就是说当局部变量与全局变量重名时,会优先使用局部变量。在函数体内定义变量时必定要使用var关键字,或者JS会查早同名全局变量并使用。 函数能够嵌套,父函数定义的变量能够在子函数内有意义。 Var space=’op’; Function par(){ Var space = ‘par’; Function son(){ Return space; } } Par(); // => par Var space=’op’; Function par(){ Var space = ‘par’; Function son(){ Var space = ‘son’; Return space; } } Par(); // => son 函数变量做用域和声明提早。 变量声明在这个函数体内以及这个函数嵌套的任意函数体内都是有定义。 JS的函数做用域意味着:定义的变量在函数体内是始终是可见,这意味这变量在在函数体内声明以前就可使用。 Var space =’global’; Function test(){ Console.log(space); //=>undefined 变量虽有定义可是没有值 Var space;space=’function’; //变量在这里赋予初始值,可是变量在函数体内都是有定义的(var space); Console.log(space); //=> function 变量以赋予初始值 } 注意:因为函数做用域的做用,在函数体内的定义变量,在函数内始终有定义,也就是说JS在检测函数有定义变量的语句时会提早声明变量,而不赋值,当执行到赋值语句的时候的才会给与变量赋值。所以上边代码等于: Var space =’global’; Function test(){ Var space; Console.log(space); //=>undefined 变量虽有定义可是没有值 Var space;space=’function’; //变量在这里赋予初始值,可是变量在函数体内都是有定义的(var space); Console.log(space); //=> function 变量以赋予初始值 } JS函数独有这个特性叫作 声明提早。 做为属性的变量: 当生命一个全局变量变量时,实际上定义了一个全局对象的属性,当经过var关键字时次属性是不可配置,不能使用delete删除此变量。当不严格的定义(不实用var)是能够经过delete删除。 JS全局变量是全局对象的属性,局部变量没定义,可是也能够想到是函数对象的属性。 JS 容许使用this来引用全局变量,可是没方法能够引用局部变量。 JS做用域链: JS是基于词法做用域的:全局变量在程序中始终有意义,局部变量在函数体内及函数嵌套的函数体内始终有意义。 若是将变量看做一个自定义实现的对象的属性,那么换一个角度来解读变量做用域。每一段代码都是有一个与之关联的做用域链。这个做用域链对应着一个对象的列表或者链表。那么当执行程序的时候,JS会一次查找每一个对象的做用域链。当发现此变量的时候就定义此变量,当没有此变量就抛出一个错误。 那么对于顶层代码来讲(不包含函数定义的语句),就会有一个全局做用域链。 对一个不包含嵌套函数的函数做用域链上包含两个对象:参数变量,局部变量的一个对象,和全局变量对象 。 对于嵌套函数来讲: 至少有三个对象::参数变量,局部变量的一个对象,和全局变量对象 。 当定义一个函数保存一个做用域链,当调用这个函数的时候,会建立一个更长的函数调用的对象加到这个做用域链,对于嵌套函数来讲更复杂,会从新定义内部函数,并建立一个新的对象加到做用域链。因次每次调用外部函数时做用域链都是不相同的。