- 目录
- 1. 序章
- 2. 计算机网络与协议
- 3. 信息收集
- 4. 常见漏洞攻防
- 5. 语言与框架
- 6. 内网渗透
- 7. 云安全
- 8. 防御技术
- 9. 认证机制
- 10. 工具与资源
- 11. 手册速查
- 12. 其他
5.4.4. 作用域与闭包
5.4.4. 作用域与闭包
5.4.4.1. 作用域与作用域链
5.4.4.1.1. 作用域
简单来说,作用域就是变量与函数的可访问范围,即作用域控制着变量与函数的可见性和生命周期。JavaScript的作用域是靠函数来形成的,也就是说一个函数的变量在函数外不可以访问。
作用域可以分为全局作用域、局部作用域和块级作用域,其中全局作用域主要有以下三种情况:
- 函数外面定义的变量拥有全局作用域
- 未定义直接赋值的变量自动声明为拥有全局作用域
- window对象的属性拥有全局作用
局部作用域一般只在固定的代码片段内可访问到,最常见的例如函数内部,所以也会把这种作用域称为函数作用域。
5.4.4.1.2. 作用域泄漏
在ES5标准时,只有全局作用域和局部作用域,没有块级作用域,这样可能会造成变量泄漏的问题。例如:
var i = 1; function f() { console.log(i) if (true) { var i = 2; } } f(); // undefined
5.4.4.1.3. 作用域提升(var Hoisting)
在JavaScript中,使用var在函数或全局内任何地方声明变量相当于在其内部最顶上声明它,这种行为称为Hoisting。例如下面这段代码等效于第二段代码
function foo() { console.log(x); // => undefined var x = 1; console.log(x); // => 1 } foo();
function foo() { var x; console.log(x); // => undefined x = 1; console.log(x); // => 1 } foo();
5.4.4.1.4. 作用域链
当函数被执行时,总是先从函数内部找寻局部变量,如果找不到相应的变量,则会向创建函数的上级作用域寻找,直到找到全局作用域为止,这个过程被称为作用域链。
5.4.4.2. 闭包
函数与对其状态即词法环境(lexical environment)的引用共同构成闭包(closure)。也就是说,闭包可以让你从内部函数访问外部函数作用域。在JavaScript,函数在每次创建时生成闭包。
在JavaScript中,并没有原生的对private方法的支持,即一个元素/方法只能被同一个类中的其它方法所调用。而闭包则是一种可以被用于模拟私有方法的方案。另外闭包也提供了管理全局命名空间的能力,避免非核心的方法或属性污染了代码的公共接口部分。下面是一个简单的例子:
var Counter = (function() { var privateCounter = 0; function changeBy(val) { privateCounter += val; } return { increment: function() { changeBy(1); }, decrement: function() { changeBy(-1); }, value: function() { return privateCounter; } } })(); console.log(Counter.value()); /* logs 0 */ Counter.increment(); Counter.increment(); console.log(Counter.value()); /* logs 2 */ Counter.decrement(); console.log(Counter.value()); /* logs 1 */
5.4.4.3. 全局对象
全局对象是一个特殊的对象,它的作用域是全局的。
全平台可用的全局对象是 globalThis
,它跟全局作用域里的this值相同。另外在浏览器中存在 self
和 window
全局对象,Web Workers中存在 self
全局对象,Node.js 中存在 global
全局对象。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论