作用域(scope)
在ECMAScript中,JavaScript只有两类作用域:全局作用域、函数作用域。
全局作用域(globe scope):全局对象的作用域,在代码的任何地方都可访问,但有时会被函数作用域覆盖。
函数作用域(local scope):作用于整个函数范围内,不管到底是在函数中的何处进行声明。
定义变量时,如果不写var。就相当于声明了一个全局变量,作用域为全局作用域;否则声明的就是局部变量,作用域为函数作用域。
作用域链(scope chain)
全局作用域和局部作用于中变量的访问权限,是有作用域链决定的。
每次进入一个新的执行环境, 都会创建一个用于搜索变量的函数的作用域链。作用域链是函数被创建的作用域中的对象的集合。作用域链的作用是可以保证对执行环境有权访问的所有变量和函数的有序访问。
作用域链的最前端始终是当前执行的代码所在环境的变量对象(如果该环境是函数,则将其活动对象作为变量对象),下一个变量对象来自包含环境,下一个变量对象来自包含环境的包含环境,以此往上,直到全局执行环境的变量对象。全局执行环境的变量对象始终是作用域链中的最后一个对象。
标识符解析是沿着作用域一级一级的向上搜索标识的过程。搜索过程始终是从作用域的前端逐渐地向后回溯,直到找到标识符。
作用域链相关知识的总结
1、执行环境决定了变量的生命周期,以及哪部分代码可以访问其中的变量。
2、执行环境有全局执行环境和局部执行环境之分。
3、每次进入一个新的执行环境,都会创建一个用于搜索变量和函数的作用域链。
4、函数的局部环境可以访问函数作用域中的变量和函数,也可以访问其父环境,乃至全局环境中的变量和环境。
5、 全局环境只能访问全局环境中定义的变量和函数,不能直接访问局部环境中的任何数据。
6、变量的执行环境有助于确定应该何时释放内存。
变量提升(variable hoisting)
JavaScript中,函数及变量的声明都将被提升到函数的最顶部。
JavaScript中,变量可以在使用后声明,也就是变量可以先使用再声明。
函数声明和变量声明总是会被解释器悄悄地“提升”到方法体的最顶部。
变量提升只是提升变量的声明,不会把变量的值也提升。
var name="hello";
function changeName(){
console.log(name);
var name="world";
}
changeName();
console.log(name);
var name="hello";
function changeName(){
var name
console.log(name);
var name="world";
}
changeName();
console.log(name);
函数提升(function hoisting)
函数提升就是把函数提升到前面。
在JavaScript中的函数的创建方式有三种:函数声明(静态的,像函数example()的形式)、函数表达式(函数字面量)、函数构造法(动态的,匿名的)。