JS学习【四】(作用域,预解析)

1. JavaScript作用域

1.1 变量的作用域

1.1.1 全局变量

  • 在全局作用域下声明的变量都是全局变量
  • 全局变量在代码任何位置都可以使用
  • 特殊情况:在函数内未声明但赋值的变量也是全局变量(不推荐)
function f(){
    
    
    num = 10;
}

console.log(num); // => 10

1.1.2 局部变量

  • 在函数内部定义的变量

1.1.3 局部变量与全局变量的区别

  • 全局变量:在任何一个地方都可以使用,浏览器关闭时才销毁
  • 局部变量:在函数内部使用,其代码执行的时候被初始化,代码块运行结束即被销毁

1.2 作用域链

  • 根据在内部函数可以访问外部函数变量这种机制,用链式查找决定哪些数据能被内部函数访问,就称为作用域链
var num = 10;
function f(){
    
    
    var num = 20;
    
    function f(){
    
    
        console.log(num);
    }
}

f(); // => 20

2. 预解析

  • js解析器在运行js代码的时候分为两步:预解析和代码执行
  • 预解析: js引擎会把js里面所有的 var 还有 function提升到当前作用域的最前面
  • 代码执行:按照代码顺序从上往下执行
  • 预解析分为变量预解析(变量提升)与函数预解析(函数提升)

2.1 变量预解析

  • 变量预解析就是把所有变量声明提升到当前作用域最前面,不提升赋值操作
  console.log(num);  // => undefined
  var num = 10;

  f2(); // => err: Uncaught TypeError: f2 is not a function
  var f2 = function () {
    
    
    console.log("I am f2");
  }

思考上述两段代码为什么打印结果在意料之外?

在预解析后,代码其实是长这样子的:

  var num;
  console.log(num);  
  num = 10;

  var f2;
  f2(); 
  f2 = function () {
    
    
    console.log("I am f2");
  }

2.2 函数预解析

  • 函数提升:把所有函数声明提升到当前作用域的最前面,不调用函数
  f1();  // => I am f1
  function f1() {
    
    
    console.log("I am f1");
  }

思考:为什么这次能够运行 ?

同理,预解析后代码长这样:

  function f1() {
    
    
    console.log("I am f1");
  }
  f1(); 

2.3 预解析思考题

  • 思考下列代码会输出什么并写出预解析后的下列代码

2.3.1

  var n = 10;
  f();  // => undefined
  function f() {
    
    
    console.log(n);
    var n = 20;
  }

预解析后:

  var n;
  function f(){
    
    
      var n;
      console.log(n)
      n = 20;
  }
  n = 20;
  f();

2.3.2

  f(); // => 9 9 9
  console.log(c); // => 9
  console.log(b); // => 9
  console.log(a); // => err: a is not defined

  function f(){
    
    
    var a = b = c = 9;
    console.log(a);
    console.log(b);
    console.log(c);
  }

预解析后:

  • 注意观察b c赋值,已成为全局变量
  function f(){
    
    
    var a;
    a = 9;
    b = 9;
    c = 9;
    console.log(a);
    console.log(b);
    console.log(c);
  }

  f();
  console.log(c);
  console.log(b);
  console.log(a);

;
b = 9;
c = 9;
console.log(a);
console.log(b);
console.log©;
}

f();
console.log©;
console.log(b);
console.log(a);


猜你喜欢

转载自blog.csdn.net/qq_43249043/article/details/108125503