js基础_31、全局作用域
作用域
作用域指一个变量的作用的范围
在js中一共有两种作用域:
1.全局作用域
—-直接编写在script标签中的js代码,都在全局作用域。
全局作用域在页面打开时创建,在页面关闭时销毁。
—-在全局作用域中有一个全局对象window,我们可以直接使用,它代表的是一个浏览器的窗口,它由浏览器创建,我们可以直接使用。
—-在全局作用域中:
我们创建的变量都会作为window对象的属性保存
比如:
var a=10;
//console.log(window);
console.log(window.a);
我们创建的函数都会作为window对象的方法保存
比如:
function fun(){
console.log('hello');
}
window.fun();
window.alert('hello');
变量的声明提前
—-使用var 关键字声明的变量,会在所有的代码执行之前被声明(但是不会赋值),但是如果声明变量时不使用关键字var声明,则变量不会被声明提前。
使用var关键字声明变量的代码,下图为使用var 关键字的原理
console.log(a);
var a=10;
如图,使用var关键字时相当于在代码执行前声明了变量a,
输出结果为undefined,但不会报错。如图:
不使用var关键字声明变量的代码,下图为不使用var 关键字的原理:
console.log(a);
a=10;
如果不使用var关键字声明就相当于不会有声明提前,如下图:
输出结果会报错,因为根本找不到这个变量,如下图:
函数的声明提前
—-使用函数声明形式创建的函数function fun (){}形式
它会在所有代码执行前就被创建,和变量声明提前一样,所以我们可以在函数声明前来调用函数。
—-使用表达式创建的函数var fun=function (){}形式
不会被声明提前,所以不能在声明前调用,因为根本没有创建函数。
实例代码:
fun1();
fun2();
function fun1(){
console.log("1");
}
var fun2=function (){
console.log("2");
};
结果如下图:
因为使用函数声明方式会将函数声明提前,而使用表达式声明函数不会,毕竟是通过变量来接收的,而变量声明提前并没有赋值,而是执行到了变量赋值所在行才赋值的。
—-全局作用域中的变量都是全局变量
在页面的任意部分都可以访问到。
2.函数作用域
—-调用函数时创建函数作用域,函数执行完毕以后,函数作用域销毁。
—-每调用一次函数就会创建一个新的函数作用域,它们之间是互相独立的。
—-在函数作用域中可以访问到全局作用域中的变量,在全局作用域中无法访问到函数作用域中的变量。
—-当在函数作用域中操作一个变量时,他会先在自身(函数)作用域中寻找,如果有就直接使用,如果没有就向上一级作用域中寻找,直到找到全局作用域中为止,如果全局作用域中依然没有找到,则会报错(ReferenceError引用异常的错误)。
如下代码就体现了就近原则:
var a=20;
function fun1(){
var a='hello'
function fun2(){
console.log(a);
}
fun2();
}
fun1();
结果如下:
如果函数作用域中不存在次变量则向上一级查找,实例代码如下:
var a=20;
function fun1(){
function fun2(){
console.log(a);
}
fun2();
}
fun1();
最后在全局作用域里找到,结果如下:
—在嵌套的函数中如果要使用全局作用域中的同名变量,而不是上一级的同名变量可以使用window对象的形式点出来。
var a=20;
function fun1(){
var a='hello'
function fun2(){
console.log(window.a);
}
fun2();
}
fun1();
—-在函数作用域中也有声明提前的特性。
使用var关键字声明的变量,会在函数中所有的代码执行之前被声明。
函数中的函数也会被声明提前,相当于函数作用域是一个小的全局作用域。
<script>
var a=20;
function fun1(){
console.log(a);
var a='hello'
}
fun1();
</script>
代码结果如下图:
因为变量声明提前没有赋值,所以为Undefined
—-在函数作用域中不写var 关键字声明的变量会称为全局变量,因为如果找不到声明该函数的关键字var(也就是这个变量没有被声明过)系统会默认为是给window对象声明的属性,所以会默认加上window.a,因为给它赋值了。
<script>
function fun1(){
a='hello'//没有var声明的变量,但是在此作用域和全局作用域却没有找到该变量时会成这样的形式window.a
}
fun1();
console.log(a);//在全局作用域里输出a
</script>
结果如下图:
如果没有使用var 声明变量但是在上一级找到该变量时,就会对它重新赋值,加了var 就不会,加了var会使它的生命周期就在该函数执行时存在。
比如:
<script>
var a=100
function fun1(){
a='hello';
}
fun1();
console.log(a);
</script>
结果如下图:
在函数括号里定义形参就相当于在函数作用域中声明了变量