导航

(六).JavaScript的数组(2)

Posted on 2022-04-15 22:37  云语不知  阅读(29)  评论(0)    收藏  举报

1.10 作用域链

  1. 定义:
作用域链:查找变量的过程
作用:    查找变量
查找规则:首先会在自身作用域找变量,找到就用
         如果没有,就去上级作用域查找,找到就用
         如果没有,一直往上找,直到全局作用域,有就用,没有就报错

作用域是一个相对概念
作用域的顶端一定是全局作用域
作用域是函数声明的时候确定的,作用域链是函数调用的时候有的,不调用不存在

作用域是虚拟的
作用域链是可见的
  1. 案例
    var a = 0;
    function fn1() {
        var a = 1;
        function fn2() {
            var a = 2;
            function fn3() {
                var a = 3;
                console.log(a);
            }
            fn3();
        }
        fn2();
    }
    fn1();
  1. 案例(说明作用域是在函数声明的时候确定的)
    var num = 10;
    function fun() {
        var num = 20;
        fun2();
    }
    function fun2() {
        console.log(num);//10
    }
    fun();

1.11 预解析(变量提升,代码提升)

  1. 定义
预解析对象:①带var的变量  ②函数声明定义的函数
预解析发生时间:在js代码开始执行之前

规则:
1.先预解析函数声明定义的函数,
  如果提升的时候发现函数同名,后面的函数会覆盖前面的函数
  函数提升的时候整体提升
2.再去提升带var的变量,提升变量的时候变量同名,会忽略,
  只提升变量名(var a),变量的值是不会提升的
3.函数表达式定义的函数,预解析规则按照带var的变量对待
 var fun1 = function(){}
4.不带var的变量,不做预解析
5.函数内部也会做预解析

☆☆☆预解析完成的代码 一行一行从上至下去执行!!!
  1. 案例题
    console.log(a);
    a = 0;

    --------------------------------------------------------
    提升前
    console.log(a);
    var a = 0;
    console.log(a);
    提升后
    var a;
    console.log(a);
    a = 0;
    console.log(a);

    --------------------------------------------------------
    提升前
    console.log(a);
    var a = '我是变量';
    function a() { console.log('我是函数') }
    console.log(a);

    提升后
    function a() { console.log('我是函数') }
    // var a 忽略
    console.log(a); //打印函数本身
    a = '我是变量';
    console.log(a); //'我是变量'

    --------------------------------------------------------
    提升前
    console.log(a());
    var a = '我是变量';
    function a() { console.log('我是函数') }
    console.log(a);

    提升后
    function a() { console.log('我是函数') }
    // var a; 失效
    console.log(a()); //undefined
    a = '我是变量';
    console.log(a); //'我是变量'

    --------------------------------------------------------
    提升前
    console.log(a);
    var a = 0;
    console.log(a);
    function fn() {
        console.log(a);
        var a = 1;
        console.log(a);
    }
    fn()
    console.log(a);

    提升后
    function fn() {
        var a;
        console.log(a); //undefined
        a = 1;
        console.log(a); //1
    }
    var a;
    console.log(a); //undefined
    a = 0;
    console.log(a); //0
    fn();
    console.log(a); //0

    --------------------------------------------------------
    提升前
    console.log(a);
    var a = 0;
    console.log(a);
    function fn() {
        console.log(a);
        a = 1;
        console.log(a);
    }
    fn()
    console.log(a);

    提升后
    function fn() {
        console.log(a); //0
        a = 1;
        console.log(a); //1
    }
    var a;
    console.log(a); //undefined
    a = 0;
    console.log(a); //0
    fn()
    console.log(a); //1

    --------------------------------------------------------
    提升前
    console.log(a);
    var a = 0;
    console.log(a);
    function fn() {
        console.log(a);
        a = 1;
        console.log(a);
    }
    fn()
    function fn() {
        console.log(a);
        var a = 1;
        console.log(a);
    }

    var fn = function () {
        console.log(a);
        a = 1;
        console.log(a);
    }
    fn();
    var a = 100;
    console.log(a);

    提升后
    function fn() {
        console.log(a);
        a = 1;
        console.log(a);
    }
    function fn() {
        var a;
        console.log(a); //undefined
        a = 1;
        console.log(a); //1
    }
    var a
    console.log(a);  //undefined
    a = 0;
    console.log(a); //0
    fn(); 
    fn = function () {
        console.log(a); //0
        a = 1;
        console.log(a); //1
    }
    fn();
    a = 100;
    console.log(a); //100

    // undefined 0 undefined 1 0 1 100

1.12 js中的堆内存和栈内存

  1. 定义
1. js代码,首先会创建全局执行上下文环境
2. 只要函数调用 不管几次 每一个都会创建执行上下文环境
3. 基本数据类型变量名和值都放在栈内存当中
4. 对象数据类型(数组 函数  对象)在栈内存中存储的是地址,数据存储在堆内存当中
  1. 程序开始到结束的整个流程
1、程序一开始执行,碰见了全局环境,首先会创建全局环境并且进行压栈,全局代码执行的时候依赖的就是全局环境当中的东西;比如 全局变量(全局变量如果存的是基本数据类型,那么这个值是直接存在栈当中的,如果这个变量存的是对象类型(函数、数组),那么数据是要在堆内存当中开辟自己的空间专门存储的。然后把堆里面这块空间的地址存给栈当中的对应变量);
2、当程序执行碰到了函数调用;函数是比较特殊,因为它也可以执行;函数执行的时候也要有自己的环境去依赖。因此函数执行也是创建自己的函数环境进行压栈(函数环境一定是压在全局环境之上的),局部变量,是在函数环境当中存在的,只有函数执行,局部变量才会出现。函数执行完成以后,函数环境要弹出栈(销毁归还内存), 局部变量也就不复存在了。
3、当函数调用完成以后,会继续执行全局代码,一直到所有的代码都执行完成,代表程序执行结束,程序结束的时候,我们的全局环境最后出栈。

1.13 基本数据类型和引用数据类型

// 基本数据类型存储的是值
// 引用数据类型存储的是地址!!!
    // 1.
    var a = 10;
    var b = a; //相当于把a身上的值(10)给了b一份 两个人都是10了
    a = 20;
    console.log(b);

    // 2.
    var arr1 = [1, 2, 3];
    var arr2 = arr1; //将arr1的地址值赋值给arr2
    arr2[1] = 22;  //修改arr1[1]与arr2[1]的值为22
    console.log(arr1);

    // 3.
    var arr1 = [1, 2, 3];
    var arr2 = arr1; //将arr1的地址值赋值给arr2
    arr2 = [1, 22, 3]; //将一个新的数组地址赋值给arr2
    console.log(arr1);

    // 4.
    var arr1 = [];
    var arr2 = [];
    var arr3 = arr1;
    arr3 = [];
    arr3[0] = 12;
    console.log(arr1, arr2, arr3); //[] [] [12]

    var arr = [1, 2, 3];
    var arr1 = [1, 2, 3];
// 对于引用数据类型判等来说,判别的是地址,地址一样就是true,地址不一样就是false
    console.log(arr == arr1);