作用域
scope
1.函数创建时,生成的一个js内部隐式属性;
2.函数存储作用域链的容器;
AO/GO
AO:函数的执行期上下文
GO:全局的执行期上下文
函数执行完成后,AO是要销毁的;AO是一个即使存储容器。
function a(){ function b(){ function c(){} c(): } b(); } a(); a定义:a.[[scope]] -> 0 : GO a执行:a.[[scope]] -> 0 : a -> AO 1 : GO b定义:b.[[scope]] -> 0 : a -> AO 1 : GO b执行:b.[[scope]] -> 0 : b -> AO 1 : a ->AO 2 : GO c定义:c.[[scope]] -> 0 : b -> AO 1 : a -> AO 2 : GO c执行:c.[[scope]] -> 0 : c -> AO 1 : b -> AO 2 : a -> AO 3 : GO c结束:c.[[scope]] -> 0 : b -> AO 1 : a -> AO 2 : GO b结束:b.[[scope]] -> 0 : a -> AO 1 : GO c.[[scope]] 完全销毁 a结束:a.[[scope]] -> 0 : GO b.[[scope]] 完全销毁
JavaScript 采用的是词法作用域(静态作用域),函数的作用域在函数定义的时候就决定了,而不是函数调用的时候才决定的。
举个例子:
var value = 1;
function foo() {
console.log(value);
}
function bar() {
var value = 2;
foo();
}
bar();
执行 foo 函数,先从 foo 函数内部查找是否有局部变量 value,
如果没有,就根据书写的位置,查找上面一层的代码,也就是 value 等于 1,所以结果会打印 1。
思考:
var a = 10;
var o = {
a:11,
b:{
fn:function(){
console.log(a);
}
}
}
o.b.fn();
执行o.b.fn,先从 fn 函数内部查找是否有局部变量a,
如果没有,就根据书写的位置,查找o上面一层的代码,也就是 a 等于 10,所以结果会打印 10。
值得注意的是:
如果是一个函数里又嵌套一个完整的函数
里面的那个函数,其作用域必然是外层的函数
var scope = "global scope";
function checkscope(){
var scope = "local scope";
function f(){
return scope;
}
return f;
}
checkscope()();
输出:local scope
注意
1.函数的作用域在函数定义的时候就决定了,而不是函数调用的时候才决定的
2.this指调用函数所处的环境(二者不要混淆)
3.作用域可以一层一层往外找;this则是按着原形链去访问它父级对象
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了