作用域与作用域链
作用域(scope):是一个变量的可用范围
作用域是从调用的时候确定的
全局作用域:任何地方都可以访问,反复使用
函数作用域(局部作用域):仅在函数内部可访问,不能反复使用
全局作用域
全局变量拥有全局作用域,在代码的任何地方都有定义。一般有两种情况变量会拥有全局作用域:
最外层函数和在最外层函数外面定义的变量拥有全局作用域
所有未定义的直接赋值的变量自动声明为全局变量,也就是拥有全局作用域
还有一个比较特殊的也拥有全局作用域,他就是window对象的内置属性。比如window.location
var scope="global"; //声明一个全局变量
function checksope(){
outScop = 'out'; //未定义的直接赋值的变量自动声明为全局变量,默认为全局变量
function showglobal(){
alert(scope); //内置属性,弹窗全局变量
}
showglobal();
}
checksope() // global 内部函数可以访问全局变量
var声明全局变量
局部作用域
局部作用域一般只在固定的代码片段内可访问到,最常见的例如函数内部。
var scope="global"; //声明一个全局变量
function checksope(){
var outScop = 'out';//局部变量,拥有局部作用域
function showglobal(){
alert(scope); //弹窗全局变量
}
showglobal();
}
checksope() // global 内部函数可以访问全局变量
outScop的作用域是在checkscope中,出了这个函数就访问不到了
块级作用域
在ES6中新增了一种作用域就是块级作用域,块级作用域和变量的声明方式有关系,那就是使用let命令用来进行变量声明,使用let命令声明的变量只在let命令所在代码块内有效。
示例代码:
{
let kuaiLet = 'oecom.cn';
}
console.log(kuaiLet)
该代码会发现报错,原因在于kuaiLet这个变量只在他所在的大括号内有效,这个大括号就是他的块级作用域。当然,如果我们修改为var声明,在下面就可以访问到,会直接输出oecom.cn
作用域链
概念:
当访问一个变量时,解释器会首先在当前作用域查找标示符,如果没有找到,就去父作用域找,直到找到该变量的标示符或者不在父作用域中,这就是作用域链
作用域链决定了各级上下文中的代码在访问变量和函数时的顺序
作用域链和原型继承查找时的区别:
如果去查找一个普通对象的属性,但是在当前对象和其原型中都找不到时,会返回undefined;但查找的属性在作用域链中不存在的话就会抛出ReferenceError。
作用域链的顶端是全局对象,在全局环境中定义的变量就会绑定到全局对象中
var scope="global"; //然后,会再一次的向上一层查找,再上一层就是全局作用域了,在这里找到了scope,至此查找结束,将之弹出
function checksope(){ //其次,就会到他的上一层checksope这个函数作用域中查找,发现也没有
var outScop = 'out';
function showglobal(){ //首先,解释器首先会在showglobal方法里面查找scope,发现这个作用域里面没有
alert(scope); //弹窗全局变量
}
showglobal(); //执行showglobal函数,这个函数中有一个scope参数,要找到该参数
}
checksope() // global 内部函数可以访问全局变量
作用域和作用域链的复杂应用:闭包
闭包的概念:
闭包是指有权访问另外一个函数作用域中的变量的函数
AO:Activive Object,即函数的活动对象。
VO:Variable Object,即变量对象。
var data = [];
var i;
i=0;
for (i < 3; i++) {
data[i] = (function (i) {
return function(){
console.log(i);
}
})(i);
}
data[0](); // 0
data[1](); // 1
data[2](); // 2
作用域与上下文的联系
一个作用域下可能包含若干个上下文
上下文(context)是用来指定代码某些特定部分中this的值
作用域是指变量的可访问性,上下文是指this在同一作用域内的值。
区别
1.全局作用域之外,每个函数都会创建自己的作用域,作用域在函数定义时就已经确定了。而不是在函数调用时
2.全局执行上下文环境是在全局作用域确定之后,js代码马上执行之前创建的
3.函数执行上下文是在调用函数时,执行函数体代码之前创建
4.作用域是静态的。只要函数定义好了就一直存在,且不会再变化
5.执行上下文环境是动态的,调用函数时创建,函数调用结束时上下文环境就会被释放
联系
执行上下文环境(对象)是从属于所在的作用域
全局上下文环境>对应全局作用域
函数上下文环境>对应的函数使用域
变量声明
var 作用域声明
使用 var 声明全局变量
在使用 var 声明变量时,变量会被自动添加到最接近的上下文
在函数中,最接近的上下文就是函数的局部上下文
声明提升:var 声明会被拿到函数或全局作用域的顶部,位于作用域中所有代码之前。
提升让同一作用域中的代码不必考虑变量是否已经声明就可以直接使用。
let 块级作用域声明
在块级作用域中使用let进行声明
块级作用域由最近的一对包含花括号{}界定
let 与 var 的一个不同之处是在同一作用域内不能声明两次。重复的 var 声明会被忽略,而重复的 let 声明会抛出SyntaxError
const 的常量声明
使用 const 声明的变量必须同时初始化为某个值
一经声明,在其生命周期的任何时候都不能再重新赋予新值
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?