javascript 作用域、作用域链理解
JavaScript作用域就是变量和函数的可访问范围。
1.变量作用域
在JavaScript中,变量作用域分为全局作用域和局部作用域。
全局作用域
任何地方都可以定义拥有全局作用域的变量
1.没有用var声明的变量(除去函数的参数)都具有全局作用域,成为全局变量,所以声明局部变量必须要用var
2.window的所有属性都具有全局作用域
3.最外层函数体外声明的变量也具有全局作用域
var globalScope="globalScope"; function checkScope(){ var partScope="part"; scope="scope"; } checkScope(); console.log(globalScope);//globalScope,全局变量 console.log(scope); //scope,全局变量 console.log(partScope);//Uncaught ReferenceError: partScope is not defined,报错:没有定义partScope
局部作用域
1.函数体内用var声明的变量具有局部作用域,成为局部变量
2.函数的参数也具有局部作用域
var globalScope="globalScope"; function checkScope(x){ scope="scope"; //变成了全局变量 var partScope="part";//在函数体内,声明局部变量一定要加var var globalScope="partScope"; } checkScope(12); console.log(globalScope);//globalScope,在函数体内,局部变量的优先级高于全局变量 console.log(scope);//scope,全局变量 console.log(partScope); console.log(partScope);// Uncaught ReferenceError: partScope is not defined,局部变量外面访问不到 console.log(x);//局部变量外面访问不到
总结:在函数体内局部变量的优先级高于同名的全局变量,声明局部变量必须用var
2.函数作用域
一些类C语言是块级作用域(block scope),每一个花括号是一个作用域,花括号内的代码对外是不可见的。而
JavaScript是函数作用域(function scope),没有块级作用域。无论函数体内的变量在什么地方声明,对整个函数都是可见的,即JavaScript函数里声明的所有变量都被提前到函数体的顶部,只是提前变量声明,变量的赋值还是保留在原位置
函数作用域只能用函数来声明独立作用域,并不是每一个花括号都是一个独立作用域,例如:for循环并不能创建一个局部的作用域
for(var i=0;i<5;i++){ var scope='scope'; } console.log(i) //5;i仍然存在,因为JavaScript是函数作用域而不是块级作用域 console.log(scope);//scope;scope仍然存在 function checkScope(){ console.log(funScope); // undefined,函数里声明的所有变量都被提前到函数体的顶部,所以funScope才会认为已经存在 var funScope="funScope"; }
checkScope();
3.作用域链
作用域链:JavaScript的变量都是对象的属性,而该对象可能又是其它对象的属性,而所有的对象都是全局对象的属性,所以这些对象的关系可以看作是一条链,
链头就是变量所处的对象,链尾就是全局对象
function checkScope(scope){ var funScope="funScope";
var s=scope;
}
在查找变量funScope的值时,会先查找当前对象,如果当前对象查不到就继续查找作用域链上面的下一个对象,如果作用域链上没有一个对象包含此属性,就抛出引用错误。
在不包含嵌套的函数体内,作用域链上有两个对象:
1.定义函数参数和局部变量的对象
2.全局对象
在包含嵌套的函数体内,作用域链上至少有三个对象
作者:绿茶叶
出处:http://www.cnblogs.com/greenteaone/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
2012-01-05 Timer(System.Timers) 和 DispatcherTimer