1.函数作用域

含义:属于这个函数的全部变量都可以在整个函数的范围内使用及复用
隐藏
遵循最小授权/最小暴露原则,将一些不需要曝露的函数、变量私有化,“隐藏”还能规避命名冲突。
规避冲突还可以全局命名空间、模块管理。

函数作用域

函数声明和函数表达式,简单的差别就是function关键词出现的位置,在最开头就是函数声明,反之表达式。
匿名函数表达式缺点:
1.栈追踪没有有意义的函数名,调试困难
2.递归时不方便
3.可读性差

2.块作用域

最常见带有常见块作用域风格的代码:for、if
但是变量会污染全局

try/catch

1
2
3
4
5
6
7
try{
undefined();//强制制造异常
}
catch(err){
console.log(err);//能执行
}
console.log(err);//ReferenceError

catch分句会创建一个块作用域,其中声明的变量仅在catch内部有效

let(es6)

let关键字可以将变量绑定到所在的任意作用域(通常在{…}内部)

1
2
3
4
5
6
var foo=true
if(foo){
let bar=3;
console.log(bar); //可取到3
}
console.log(bar); //ReferenceError

let声明了一个if{..}块的变量 在块作用域外取不到
块作用域非常有用的原因和闭包及回收内存垃圾的机制相关,可以将执行一次就销毁的块显示声明
{
let a={};
do(a);
}

const(es6)

也可以用来创建块作用域

1
2
3
4
5
6
7
8
9
10
var foo=true;
if(foo){
const a=2;
var b=3;
a=3; //非法
b=4; //正确
}
console.log(a); //ReferenceError
console.log(b); //4

const声明的变量,也会劫持块作用域,且声明之后就不能修改