作用域是可访问变量的集合。
在JavaScript中,对象和函数同样也是变量;所以作用域为可访问变量、对象、函数的集合;函数作用域:作用域在函数内修改。
- JavaScript局部作用域
变量在函数内声明,变量为局部变量,具有局部作用域。局部的变量只能在函数内部访问。
function fn1() {
var name = 'Jane' //局部变量
// 这里可以访问name
console.log(name); //Jane
}
fn1();
// 这里不能访问name
//console.log(name); //直接报错,找不到这个变量
因为局部变量只能作用在函数内,所以不同的函数可以使用相同名称的变量。
function fn1() {
var name = 'Jane' //fn1的局部变量
console.log(name); //Jane
}
fn1();
function fn2() {
var name = 'Tom'; //fn2的局部变量
console.log(name); //Tom
}
fn2();
局部变量在函数开始执行的时候创建,函数执行完毕之后局部变量会自动销毁。
- JavaScript全局变量
变量在函数外定义,就是全局变量;全局变量有全局作用域;网页脚本和函数均可使用。
var age = 18; //全局变量
function fn1() {
var name = 'Jane' //fn1的局部变量
console.log(name,age); //Jane 18
}
fn1();
function fn2() {
var name = 'Tom'; //fn2的局部变量
console.log(name,age); //Tom 18
}
fn2();
// 这里两个函数都能访问到全局变量 age
注:如果在函数中没有声明变量,该变量也是全局变量
var age = 18; //全局变量
function fn1() {
var name = 'Jane' //fn1的局部变量
console.log(name,age); //Jane 18
}
fn1();
function fn2() {
var name = 'Tom'; //fn2的局部变量
hoppy = 'shuijiao'
console.log(name,age); //Tom 18
}
fn2();
console.log(hoppy); // '睡觉'
在HTML中,未声明的变量会被绑定到window对象上面。注:所有数据的变量都属于window对象
- JavaScript变量生命周期
变量生命周期在它声明的时候初始化;局部变量在函数执行完之后销毁;全局变量在页面关闭之后销毁。
- 函数参数
函数参数只在函数内起作用,也是局部变量。
- 作用域链
作用域链本质上是一个包含了变量对象的列表。这个列表的顶端是当前执行的上下文(即当前的变量对象),下面是外部函数的变量对象,再下面是外部函数的外部函数的变量对象,以此类推,一直到全局执行上下文。
扩展:将局部变量暴露给外部作用域的方式:
- 通过全局对象:在函数内部,可以通过将局部变量赋值给 window 对象的属性来使其成为全局可访问的。例如,使用 window.a = a; 语句,可以在函数外部通过 window.a 访问到这个局部变量的值。
- 定义全局变量:在函数内部不使用 var、let 或 const 等关键字声明变量时,该变量会被视为全局变量,从而可以在函数外部访问。但这种做法通常不推荐,因为它可能导致意外的副作用和代码难以维护。
- 返回值:可以通过在函数内部使用 return 语句返回局部变量的值,然后在函数外部接收这个返回值。这样,虽然局部变量本身不会被暴露,但其值可以通过函数调用传递到外部。
- 闭包:JavaScript 中的闭包特性允许内部函数访问外部函数的局部变量。即使外部函数执行完毕后,其局部变量仍然可以被内部函数引用。
- 属性和方法:定义在全局作用域中的变量和函数都会变成 window 对象的属性和方法,因此可以在调用时省略 window,直接使用变量名或函数名。
小编推荐使用,返回值和闭包的方式来实现外部作用域访问局部变量,使用方式详解: