JavaScript作用域
作用域的概念:一段程序代码中所用到的名字并不总是有效/可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。总的来说,作用域是可访变量的集合。
作用域包括:全局作用域和局部作用域。
变量(函数)包括:全局变量(函数)和局部变量(函数)。但是全局变量相比局部变量在工作中时,用的会要少一些。
1.1 全局作用域
全局作用域:指网页中都是有效的,不属于任何一个函数的区域,叫做全局作用域。
全局变量:在全局作用域中的定义的函数叫做全局函数,全局函数在当前代码内的任何区域都可以拿到。
全局函数:在全局作用域中的定义的变量叫做全局变量,全局变量在当前代码内的任何区域都可以拿到。
生命周期:随着程序的执行一直存在,但在页面关闭的时候被销毁。
var a = 1;
function fn(){
console.log(a); //1,在此处的变量a可以拿到全局变量
}
fn();
console.log(a); //1,全局变量在任何地方都可以拿到
//在全局作用域拿不到局部作用域的函数,所以显示fn1未定义
function box(){ //全局函数
function fn1(){ //局部函数
console.log("hello");
}
}
box();
fn1(); //fn1 is not defined
1.2 局部作用域
局部作用域:局部作用域一般只在固定的代码片段内可访问到,最常见的例如函数内部,所以在一些地方会把这种作用域成为函数作用域。
局部变量:在局部作用域的定义的变量叫做局部变量,局部变量的作用区域,只能在当前的局部作用域可以拿到。如果变量在函数内没有声明(没有使用var关键字),那么该变量叫做全局变量。
局部函数:在局部作用域的定义函数叫做局部函数,局部函数的作用区域,只能在当前的局部作用域可以拿到。
生命周期:作用域声明开始的时候被创建,作用域结束的时候被删除。
//当局部作用域里边没有定义某个变量,那么当打印时会向上一层寻找这个变量的定义,直到找到位置。
var a = 1;
function fn(){
//经过预编译,局部变量里边只定义了a变量,但未赋值。
console.log(a); //undefined
var b = 2; //局部变量的生命周期开始
var a = 10;
console.log(a); //10,在此处的变量a就近原则
console.log(b); //2
} //局部变量的生命周期在此结束
fn();
console.log(b); //b is not defined
//在此处的变量b拿不到函数内部的变量
function box(){
var a = 10;
function fn(){
//经过预编译,局部函数里边只定义了a变量,但未赋值。
console.log(a); // undefined
var a = "hello";
var b = 20;
console.log(a); // hello,就近原则
console.log(b); // 20
}
fn();
console.log(a); // 10,全局作用域的数值拿不到局部作用域的值
console.log(b); // b is nit defined
}
box();
1.3局部的变量和全局变量同名
//当两个函数同级是,两者里边的变量都相当于局部变量,都互相拿不到对方里边的内容。
var a = "hello";
function box(){
console.log(a); //hello
}
function fn(){
var address = "world";
box();
}
fn(); //hello
function box(){
var a = 10;
function fn(){
// 在局部变量的没有声明,那么该变量为全局作用域中的变量
a = "hello"; //相当于给全局变量重新赋值
var b = 20;
console.log(a); // hello
}
fn();
console.log(a); // hello
}
box();
1.4 为什么尽量使用局部变量
全局变量的缺点:
- 定义全局变量最大的问题是污染了命名空间,不利于代码模块化,削弱了程序灵活性,增大了模块之间的耦合性 。
- 当全局变量在整个 JavaScript 应用或 Web 页面内共享。它们生存于同一个全局命名空间内,总有可能发生命名冲突。
- 当一个应用程序中两个独立的部分定义了同名的全局变量,但却有不同目的时 ,但是后一个变量的值会覆盖前一个变量的值。
局部变量的优点:
- 全局变量一旦程序运行,系统就会分配一部分内存空间存储全局变量,直到程序关闭,全局变量才会释放。而局部变量,在子程序内工作完成,便会自动释放。
- 当和别人一起写项目,文件合并时,它们都属于局部变量,不可能发生命名冲突,不可能污染命名空间。
1.5 总结
1.变量的访问规则为:
- 父作用域的变量不能拿子作用域的变量
- 子作用域的变量可以使用父作用域中的变量
- 当子作用域中的变量没有定义时,那么该变量便会上升为全局变量。
2.当写项目时为了避免全局名称空间被污染,减少全局变量数量,避免全局变量污染 ,要尽量使用局部变量,但不意味着不要全局变量,全局变量是必要的,定义的模块也需要暴露一个全局变量供给其他代码调用。