2.4 JavaScript 作用域与预解析

声明:本人前端学习笔记的所有内容均为b站上pink老师课程的学习笔记,如果想详细了解的可以搜索以下网址:

  1. H5C3+移动布局: 黑马程序员pink老师前端入门视频教程 HTML5+CSS3+移动端布局-flex布局rem布局响应式布局摹客蓝湖使用-简单有趣好玩
  2. JavaScript系列 :JavaScript基础语法-dom/bom-es6-jQuery-数据可视化echarts-包含笔记源码作业黑马程序员pink老师前端入门视频教程(持续更新)

文章目录

  • 一、 JavaScript 作用域
    • 1. 作用域
    • 2. 变量作用域
    • 3. 作用域链
  • 二、JavaScript 预解析
    • 1.预解析
    • 2. 预解析案例


一、 JavaScript 作用域

1. 作用域

JavaScript 的作用域就是代码名字(变量)在某个范围内起作用和效果,目的是为了提高程序的可靠性,重要的是减少命名冲突。

JavaScript的作用域(es6)之前:全局作用域和局部作用域

全局作用域:整个script标签或者是一个单独的 js 文件

局部作用域(函数作用域):在函数内部就是函数作用域,这个代码的名字只能在函数内部起效果和作用

2. 变量作用域

变量的作用域:根据作用域的不同,我们变量分为全局变量和局部变量

全局变量:在全局作用域下声明的变量(在函数外部定义的变量)

  • 全局变量在代码的任何位置都可以使用
  • 在全局作用域下,var声明的变量就是全局变量
  • 特殊情况下,在函数内部不使用var变量声明的变量也是全局变量(不建议使用)
// 注意 如果在函数内部 没有声明直接赋值的变量也属于全局变量
var num = 10; // num就是一个全局变量
console.log(num); //10

function fn() {
     
    console.log(num);
    num2 = 20; //num2为全局变量
}
fn(); //10
console.log(num2); //20

局部变量:在局部作用域下声明的变量叫做局部变量(在函数内部定义的变量)

  • 局部变量只能在该函数内部使用
  • 在函数内部var声明的变量就是局部变量
  • 函数的形参实际上就是局部变量
// 注意: 函数的形参也可以看做是局部变量
function fun(aru) {
     
    var num1 = 10; // num1就是局部变量 只能在函数内部使用    
}
fun();
console.log(num1); //10

全局变量和局部变量的区别

  • 全局变量:在任何一个地方都可以使用,只有在浏览器关闭时才会被销毁,因此比较占用内存
  • 局部变量:只在函数内部使用,当其所在的代码块被执行时,会被初始化;当代码块运行结束后,就会被销毁,因此更节省内存空间

块级作用域

js中没有块级作用域,只有在es6的时候新增块级作用域

//块级作用域 if{} for{}
if (3 < 5) {
     
	var num = 10;
}
console.log(num); //外面的是不能调用num的

3. 作用域链

作用域链 : 内部函数访问外部函数的变量,采取的是链式查找的方式来决定取那个值 这种结构我们称为作用域链 就近原则

var num = 10;
function fn() {
      // 外部函数
    var num = 20;
    function fun() {
      // 内部函数
        console.log(num); //20(就近原则)
    }
    fun();
}
fn();
// 案例1 : 结果是几?
function f1() {
     
    var num = 123;
    function f2() {
     
        var num = 0;
        console.log(num); // 0   站在目标出发,一层一层的往外查找
    }
    f2();
}
var num = 456;
f1();

// 案例2 :结果是几?
var a = 1;
function fn1() {
     
    var a = 2;
    var b = '22';
    fn2();
    function fn2() {
     
        var a = 3;
        fn3();
        function fn3() {
     
            var a = 4;
            console.log(a); //a的值 4
            console.log(b); //b的值 22
        }
    }
}
fn1();

二、JavaScript 预解析

1.预解析

我们 js 引擎运行 js 分为两步: 预解析 代码执行

  • 预解析:js引擎会把 js 里面所有的 var 还有 function 提升到当前作用域的最前面

  • 代码执行:按照代码书写的顺序从上往下执行

预解析分为 变量预解析(变量提升)函数预解析(函数提升)

  • 变量提升:就是把所有的变量声明提升到**当前的作用域最前面** 不提升赋值操作
  • 函数提升:就是把所有的函数声明提升到**当前作用域的最前面** 不调用函数
// 1问  
console.log(num); //报错!

// 2问
console.log(num); // undefined  坑 1
var num = 10;
// 相当于执行了以下代码
// var num;
// console.log(num);
// num = 10;

// 3问  
function fn() {
     
    console.log(11);
}
fn();

// 4问
fun(); // 报错  坑2 
var fun = function() {
     
    console.log(22);
}
// 相当于执行了以下代码
// var fun;
// fun();
// fun = function() {
     
//   console.log(22);
//}

2. 预解析案例

// 案例1
var num = 10;
fun();
function fun() {
     
     console.log(num); //undefined
     var num = 20;
}

// 相当于执行了以下操作
// var num;
// function fun() {
     
//     var num;
//     console.log(num);
//     num = 20;
// }
// num = 10;
// fun();
// 案例2
var num = 10;
function fn() {
     
    console.log(num);  //undefined
    var num = 20;
    console.log(num);  //20
}
fn();

// 相当于以下代码
// var num;
// function fn() {
     
//     var num;
//     console.log(num);
//     num = 20;
//     console.log(num);
// }
// num = 10;
// fn();
// 案例3
f1();
console.log(c);
console.log(b);
console.log(a);

function f1() {
     
    var a = b = c = 9;
    console.log(a);
    console.log(b);
    console.log(c);
}
//最后输出 9 9 9 9 9 报错

// 以下代码
// function f1() {
     
//     var a;
//     a = b = c = 9;
//     // 相当于 var  a  = 9; b = 9; c = 9; b 和 c 直接赋值 没有var 声明 当 全局变量看
//     // 集体声明  var a = 9, b = 9, c = 9;
//     console.log(a);
//     console.log(b);
//     console.log(c);
// }
// f1();
// console.log(c);
// console.log(b);
// console.log(a);

你可能感兴趣的:(前端学习笔记,javascript)