### 1.全局作用域,直接声明在window中的,如var a=1;不会被浏览器垃圾回收器回收
### 2.局部作用域,声明在函数内的,在函数调用后会被垃圾回收器回收,闭包除外
//全局作用域
```
function demo(){
var a="hello";//局部作用域
}
```
### 3.词法作用域:
词法作用域就是定义(声明)词法作阶段的作用域,这个跟声明时的的作用域有关,与调用时无关:例题:
//全局window作用域:包含一个标识符:foo
```
function foo(a){//foo作用域:包含三个标识符:a,b,bar
var b=a*2;
function bar(c){//bar作用域:包含一个标识符:c
console,log(a,b,c);
}
bar(b*3);
}
foo(2);//2,4,12
```
### 例题二:
var a=1;//全局作用域:包含3个标识符:a(全局变量),fn1,fn2
function fn1(){//fn1作用域
console.log(a);
}
function fn2(){//fn2作用域:包含一个标识符:a(局部变量)
var a=3;
fn1();
}
fn2();//1
### 总结:无论函数在哪被调用,他的词法作用域只由函数被声明时候所处的位置决定。(除去eval和with//性能很差不推荐使用);
### 4.函数作用域
任意代码片段外部添加包装函数,可以将内部的变量和定义隐藏起来,外部作用域无法访问包装函数内部的任何内容。
> 比如:
```
var a=2;
function foo(){
var a=3;
console.log(a);//3
}
foo();
console.log(a);//2;
```
访问不到函数中的a
在上面中foo属于window下的全局变量,这样本身函数名会污染了其所在的作用域,所以出现了立执行函数(IIFE)
```
(function foo(){
var a=3;
console.log(a);//3
})()
```
### 提升:
> 变量提升
> 函数提升
### 变量提升:
在声明致歉被调用了,只有声明本身会被提升,而赋值或者其他运行逻辑都会处于等待状态,会改变代码的执行顺序;
例如
```
foo()//undefined
function foo(){
console.log(a);
var a=2;
}
```
函数提升了,但确仍然执行了变量提升却不行,所以以上代码相当于:
```
function foo(){
var a;
console.log(a);
a=2;
}
foo()
```
先编译后执行,所以赋值在输出之后才执行;
函数表达式不会提示;
例:
`foo()//报错`
`var foo=function(){}....`
这里函数表达式存储在变量foo中,提前调用会是underfined,但是函数对undefined进行调用时会报错。
### 函数优先:
在多个重复声明的代码中,函数声明会首先被提升,然后是变量
例如:
```
foo();//1
var foo;
function foo(){
console.log(1);
}
foo=function(){
console.log(2);
}
```
例题:
```
//考察变量声明提升,跟执行过程无关
var name = "hello";
(function() {
//这里用到了name,会现在function作用域里找,结果是先调用后声明的,所以会是undefined;
if (typeof name === "undefined") {
var name = "world";
}
})()
```
**____**下一章闭包,明天更,每日一更