作用域指一个变量的作用范围。
作用域分两种:
全局作用域函数作用域直接在script标签中编写的JS代码都属于全局作用域
全局作用域在页面打开时创建,在页面关闭时销毁在全局作用域中有一个全局对象window,它代表的是一个浏览器的窗口,它由浏览器创建我们可以直接使用在全局作用域中:
创建的变量都会作为window对象的属性保存创建的函数都会作为window对象的方法保存全局作用域中的变量都是全局变量,在页面的任意的部分都可以访问
使用var关键字声明的变量,会在所有的代码执行之前被声明,但其赋值不会被提升 但是如果声明变量时不是用var关键字,就不会被提升
console.log(a); var a = 123; //打印结果为undefined,变量a被提前声明,但赋值不会 console.log(a); a = 123; //程序出错函数声明 使用函数声明的形式创建的函数function foo(){},会被声明提前 用这个形式创建的函数的整个函数会在所有代码执行之前被创建完成,所以我们可以在函数声明之前调用函数
函数表达式 使用函数表达式创建的函数var foo = function(){},不会被声明提前,所以不能在声明前调用 因为声明的是foo且为undefined,所以不会将赋值,也就是 function(){}提前,所以浏览器会报错说foo不是一个函数
作用域:
变量和函数生效的区域。作用域在函数定义时,就已经确定了
在函数作用域中可以访问到全局作用域的变量,在全局作用域中无法访问到函数作用域的变量
执行期上下文:
当函数执行时,会创建一个执行期上下文的内部对象。
每调用一次函数,就会创建一个新的上下文对象,他们之间是相互独立的。
当函数执行完毕,它所产生的执行期上下文会被销毁
注意:
当函数内部的变量被另外一个函数所引用,那么这个函数的变量将不会在执行完毕后销毁
而当内部函数被保存到外部时,将会生成闭包。闭包将会导致作用域链不释放内存,导致内存泄露
作用域的上下级关系:
当在函数作用域操作一个变量时,它会先在自身作用域中寻找,如果有就直接使用(就近原则)。 如果没有则向上一级作用域中寻找,直到找到全局作用域;如果全局作用域中依然没有找到,则会报错ReferenceError
在函数中要访问全局变量可以使用window对象。 (比如说,全局作用域和函数作用域都定义了变量a,如果想访问全局变量,可以使用window.a)
注意点1:
在函数作用域也有声明提前的特性
使用var关键字声明的变量,会在函数中所有的代码执行之前被声明函数声明也会在函数中所有的代码执行之前执行因此,在函数中,没有var声明的变量都是全局变量,而且并不会提前声明
var a = 1; function foo() { console.log(a); a = 2; // 此处的a相当于window.a,不提前声明 } foo(); console.log(a); //打印结果是2输出:
如果去掉第一行,输出:
注意点2:
定义形参就相当于在函数作用域中声明了变量