JavaScript 的作用域
声明提前
定义:即在还没有定义该变量或函数之前,就可以使用该变量或函数了,不会出现报错情况。
变量声明提前
使用 var 声明的变量,会在所有代码执行之前被声明,但是不会被赋值。
console.log(x);
var x = 10; // x 会被提前声明
等价于
var x;
console.log(x);
x = 10;
浏览器解析器会在 console.log(x);语句之前声明 x 变量,但是没有赋值,x 为 undefined,控制台输出 undefined ,并不会出现错误。但是如果声明变量时,不使用 var 关键字,变量 x 不会提前声明,则出现错误。
函数声明提前
- 如果使用
函数声明的方式创建函数,该函数(包括函数名和函数体)会在所有代码执行之前被创建,所以可以在函数被创建之前调用该函数。
fun(); //函数被声明之前调用该函数
function fun(){ //函数声明
alert("123");
}
- 使用
函数表达式的方式创建函数,不会被提前声明,所以不能在函数被创建之前调用该函数。
//fun(); //出现错误
console.log(fun); //输出 undefined
var fun = function(){
alert("123");
}
等价于
var fun; //变量提前声明,并未赋值
//fun();
console.log(fun); //输出 undefined
fun = function(){
alert("123");
}
作用域的分类
- 全局作用域
- 函数作用域
前面说过了,JavaScript 中是没有块级作用域的,{} 只是将多个语句合成了一条语句而已,但是函数中的 {} 语句中定义的变量,{} 外是不可访问的。
全局作用域
- 直接编写在 script 标签中的 JS代码,都在全局作用域中。
- 生命周期:页面打开时创建,页面关闭时销毁。
- 在全局作用域中有一个全局对象 window ,它代表浏览器的窗口,属于宿主对象。由浏览器自动创建,我们直接使用即可。当我们创建一个全局变量时,这个变量作为 window 的属性保存;当我们创建一个函数时,这个函数作为 window 的方法保存。只是在平时的使用中,我们可以省略 window 对象的书写。
var a =123;
//window.a = 456; //等价上变量声明
var fun = function(){
alert("我是fun方法");
}
//window.fun = function(){ //等价上函数声明
//alert("我是window的方法");
//}
console.log(a);
//console.log(window.a); //等价上面一行
fun();
//window.fun(); //等价上面一行
- 在页面中的任意位置多可以访问得到全局变量或全局函数。
函数作用域
- 在函数内编写的代码,属于函数作用域。
- 声明周期:在函数被调用时创建,在函数执行完成后销毁。
- 每调用一次函数(同一个函数也是),就会创建一个新的函数作用域,他们之间是独立的。
- 在函数作用域中可以使用全局作用域中声明的变量或函数,但是在全局作用域中不可以使用函数作用域中声明的变量或函数。
在函数作用域中可以使用全局作用域中声明的变量,如下:
var a=123;
function fun(){
console.log(a); //输出 123。
}
fun();
在全局作用域中不可以使用函数作用域中声明的变量,如下:
function fun(){
var a=123;
}
fun();
console.log(a);
报错,a 没有声明。
- 当在某个作用域中操纵一个变量或函数时,首先会在该作用域中查找变量或函数,如果存在,直接使用;如果不存在,则向上一级作用域查找,直到全局作用域,如果全局作用域也不存在,则报错。也就是说:如果出现同名的变量或函数,内层作用域的变量或函数会屏蔽外层作用域的变量或函数。
var a="我是全局变量 a";
function fun(){
var a = "我是函数变量 a";
console.log(a);
}
fun(); //输出 我是函数变量 a
- 当函数作用域和全局作用域中出现了同名的变量或函数时,需要在函数的作用域中使用全局作用域的变量或函数时,需要指明使用 window 这个对象的变量或函数。
var a="我是全局变量 a";
function fun(){
var a = "我是函数变量 a";
console.log(window.a);
}
fun(); //输出 我是全局变量 a
- 在函数作用域内也会出现变量和函数声明提前的情况。
var a="我是全局变量 a";
function fun(){
console.log(a);
var a = "我是函数变量 a";
}
fun();
输出 undefined,上面代码等价于下面的代码
var a="我是全局变量 a";
function fun(){
var a;
console.log(a);
a = "我是函数变量 a";
}
fun();
- 当在函数作用域中,没有使用 var 关键字来声明变量或函数,这个变量或函数会声明成全局作用域中的变量或函数。
var a=123;
function fun(){
console.log(a); //输出全局变量 a 的值:123
a = 456; //改变全局变量 a 的值为456
b = 789; //声明一个全局变量 b 的值为789,如果使用了 var 关键字来声明 b , b 即为函数作用域的变量
}
fun();
console.log(a);
console.log(b);
这里的 a 、b 就是 window.a、window.b;
- 当定义了形参,就相当于在函数中使用 var 声明了变量
var a=123;
function fun( a ){
console.log(a);
}
fun(456); //输出 456
相当于
var a=123;
function fun( a ){
var a = 456
console.log(a);
}
fun();

本文详细介绍了JavaScript的作用域,包括声明提前、全局作用域和函数作用域。变量声明提前中,var声明的变量会被提升但未赋值,而函数声明则会被整体提升。全局作用域在页面打开时创建,关闭时销毁,函数作用域在每次函数调用时创建并销毁,其内部可以访问全局作用域,但反之不行。函数作用域内的变量和函数也会有声明提前现象,未使用var声明的变量会成为全局变量。最后,同名变量或函数在内层作用域会屏蔽外层的,需要显式引用window对象来访问全局变量。
820

被折叠的 条评论
为什么被折叠?



