JS变量提升和作用域

一.JS变量提升

1.当浏览器引擎解析js代码时,将js中的所有一开始就是var声明的和function声明的都提升到全局。此时又叫全局作用域

1   console.log(aa);
2   console.log(ff);
3   console.log(bb);
4   
5   var aa = "aa";
6 
7   function ff(){
8     console.log("ff");
9   }

注意:undefined和is not defined是不一样的。

  • undefined:声明了该变量但是调用时没有定义值

  • is not defined:没有声明也没有定义值

2.对于函数也一样,又叫做局部作用域

 1   function ff(){
 2 
 3     console.log(aa);
 4     console.log(fun);
 5     console.log(bb);
 6     var aa = "aa";
 7     function fun(){}
 8 
 9   }
10 
11   ff();

3.作用域分类

  • 全局作用域

  • 函数作用域

  • 块作用域(ES6才有)

注:查找作用域先从当前作用域查找再找上层作用域

例1:

1   var x = 10;
2   function fn() {
3     console.log(x);
4   }
5   function show(f) {
6     var x = 20;
7     f();
8   }
9   show(fn);   //10

分析:

  • 全局作用域
    • var x
    • function fn
    • function show
  • 函数作用域fn
  • 函数作用域show
    • var x

注意此处两个函数作用域是同一级的

执行到console.log(x)时,会先看fn()的函数作用域内是否有x变量没有就出去看全局的(由于show和fn为同一级所以不会看show),则此时x = 10;

例2:

 1   var fn = function () {
 2     console.log(fn)
 3   }
 4   fn()  
 5 
 6   var obj = {
 7     fn2: function () {
 8       console.log(fn2)
 9     }
10   }
11   obj.fn2()  

分析:

  • 全局作用域:
    • var fn
    • var obj
  • 全局中无函数作用域

第一个fn():会执行console.log(fn)在函数中没有fn,找全局发现fn变量是一个函数则返回函数

第二个obj.fn2():会执行console.log(fn2)在函数中没有发现fn2,不回去找obj对象中的fn2由于没有对象作用域这个东西,则找全局也没有找到报错了。

如果稍微修改以下将fn2改为this.fn2则不会报错,绑定调用对象obj然后调用obj的fn2。

 1   var fn = function () {
 2     console.log(fn)
 3   }
 4   fn()
 5 
 6   var obj = {
 7     fn2: function () {
 8       console.log(this.fn2)
 9     }
10   }
11   obj.fn2()

4.上下文栈

由于和其他语言的压栈方式相同则不在赘述

猜你喜欢

转载自www.cnblogs.com/zhihaospace/p/12003047.html