函数 作用域和块作用域
1. 函数中的作用域
属于这个函数中的全部变量都可以在整个函数的范围内使用及复用(事实上在嵌套的作用域中也可以使用)。能充分利用javascript变量可以根据需要改变值类型的“动态”特性。
2. 隐藏内部实现
在所写的代码中挑选出一个任意的片段,然后用函数声明对它进行包装,实际上就是把这些代码“隐藏”起来了。
3. 规避冲突
隐藏作用域中的变量和函数所带来的另一个好处,是可以避免同名标识符之间的冲突。
-
全局命名空间:
当程序中加载了多个第三方库时,他们会将内部私有的函数和变量隐藏,这些库通常会在全局作用域中声明一个名字足够独特的变量,通常是一个对象,所有需要暴露给外界的功能都会称为这个对象的属性。 -
模块管理
从众多模块管理器中挑选出一个来使用。通过依赖管理器的机制将库的标识符显式地导入到另外一个特定的作用域中。
4. 函数作用域
在任意代码片段外部添加包装函数,可以将内部的变量和函数定义“隐藏”起来,外部作用域无法访问包装函数北部的任何内容。如:
var a = 2;
function foo() { // <-- 添加这一行
var a = 3;
console.log( a ); // 3
} // <-- 以及这一行
foo(); // <-- 以及这一行
console.log( a ); // 2
但是这种必须声明一个具名函数foo(),意味着污染,而且必须显式的通过函数名调用这个函数的代码。
解决方法:
使用立即执行函数表达式:IIFE(Immediately Invoked Function Expression)
(function(){})()或者(function(){}()),两种形式在功能上一致,任意选择
5. 块作用域
块作用域是一个用来对之前的函数隐藏扩展到块中隐藏信息的一种方法。
try/catch
中声明的变量仅在catch内部有效
- let 方法
let关键字可以将变量绑定到所在的任意作用域中,外部作用域不能访问到。
好处:
帮助浏览器垃圾收集:
function process(data) {
// 在这里做点有趣的事情
}
var someReallyBigData = { .. };
process( someReallyBigData );
var btn = document.getElementById( "my_button" );
btn.addEventListener( "click", function click(evt) {
console.log("button clicked");
}, /*capturingPhase=*/false );
click函数的点击回调并不需要someReallyBigData变量。理论上意味着这当process()执行完毕后被回收,但是click函数形成了一个覆盖整个作用域的闭包,JavaScript引擎极有可能依然保存着这个结构。
但块作用域可以解决这个问题:
function process(data) {
// 在这里做点有趣的事情
}
// 在这个块中定义的内容可以销毁了!
{
let someReallyBigData = { .. };
process( someReallyBigData );
}
var btn = document.getElementById( "my_button" );
btn.addEventListener( "click", function click(evt){
console.log("button clicked");
}, /*capturingPhase=*/false );
所以为变量显式的声明块作用域,并对变量进行本地绑定是很有用的工具。
网友评论