作用域是指一段代码的有效范围,在JavaScript中分为全局作用域和局部作用域。全局作用域值得是global对象(window对象),局部作用域则是在全局下的函数或对象的作用域。局部作用域可以访问全局作用域,而全局作用域不可以访问局部作用域。
上下文,JavaScript使用了上下文的概念对应着作用域。
执行上下文: 全局上下文、 局部上下文
创建一个上下文:
1. 准备
创建新的作用域
创建变量、函数和参数
确定this关键字的值
2. 执行
现在可以给变量赋值
引用函数来执行其代码
执行语句
在准备阶段先创建一个variables对象,保存了上下文中的变量、函数和参数,在variables对象先创建一个arguments数组存放传过来的参数,然后在创建上下文中函数属性(将上下文中函数作为variables对象的属性),最后存放变量属性。执行阶段,执行函数体中的代码,一行一行地运行代码,给variables对象中的变量属性赋值。
第一个创建全局上下文,将全局上下文放在栈顶部,优先执行。当执行上下文时,最先执行函数,这时会创建函数的上下文,并将其顶到栈顶,因为在栈顶优先处理的元素,所以同名变量中局部作用域比全局作用域优先级要高。
(function(){ console.log(typeof foo); //function console.log(typeof bar); //undefind var foo = 'hello'; var bar = function(){ return 'world'; } function foo(){ return 'hello'; } })()
因为准备阶段查询上下文并创建variables对象的属性,所以只是创建了这些变量并没有赋值。但是函数foo()是可以执行,说明函数的创建在创建这些属性之前。执行阶段,每次赋值就会覆盖掉这些属性。