JavaScript中的数据储存(01-EC和作用域链--JS进阶)

本篇学习总结简要概述JavaScript语言代码预解析与执行的过程,以及在这过程中内存的分配与释放。关键字:JavaScript、代码段、预解析、行上下文EC、作用域、作用域链。
摘要由CSDN通过智能技术生成

JavaScript中的数据储存(执行上下文EC、栈空间ECS、堆空间)

摘要

本篇学习总结简要概述JavaScript语言代码预解析与执行的过程,以及在这过程中内存的分配与释放。

本文通过浏览器对JS代码在代码段内与代码段间的执行特点,引出代码执行的过程,运用《蛋与杯子的存放和取出》的通俗而又生动的比喻,归纳总结代码从被浏览器预解析,形成执行上下文EC==>入栈==>执行==>出栈(释放内存)的主要路线,以及在执行阶段执行上下文的内数据的指向、作用域对数据的限制特点、作用域链发挥的用处。最后运用大量习题反复巩固知识点,形成系统知识体系,并引出闭包和原型链知识点的思考。

关键字:JavaScript、代码段、预解析、行上下文EC、作用域、作用域链。

一、JavaScript代码段的概念

1. 什么是代码段:
在JavaScript(下面一律称作JS)中,一对<script> </script> 标签之间就是一个代码段。浏览器对一个代码段内JS代码预解析完成后,按从上到下的顺序执行代码。

2. 代码段内部代码执行的特点:
在一个代码段内,代码出现错误,浏览器就会在控制台(Console),打印出错误类型及错误位置,并停止错误位置以下的代码执行,开始下一个代码段内代码的预解析与执行。

3. 代码段间代码执行的特点:
每一个代码段之间是彼此独立的,浏览器在执行代码时,如果上面的代码段报错,浏览器会跳到下一段代码,上一段代码不会影响下面的代码段的执行。

4. 一个页面中可以有多个代码段


<script>
    var a = 110;
    console.log(a);//110

    // 使用了没有声明的变量
    console.log(c);
    // 报错:ReferenceError  引用错误
    // 同一个代码码段如报了引用错误,这个代码段的错误位置以下的代码停止执行
    console.log(a);//不执行
</script>




<!-- 一张页面中可以有多个代码段 -->
<script>
    var b = 220;
    console.log(b);
    // 上面的代码段中定义数,在下面的代码中可以执行
    console.log(a);
</script>

控制台打印结果:

在这里插入图片描述

二、浏览器中JavaScript语言的执行

在代码段内,JS代码不是随意访问的,而是遵循严格的规则:全局作用域下的代码可以在代码段内被全局访问,局部作用域下的代码只能在本作用域内访问。

在浏览器中,JS代码执行过程可分解为两个阶段:预解析阶段(也称:预编译阶段)、代码执行阶段

浏览器预解析完(声明提升),马上执行代码(赋值或赋值或者赋地址),是一个连续的过程

2.1 浏览器对JS代码预解析时都做了些什么?预解析与代码执行的过程具体是怎样的?

1. 声明提升:
加var的变量 提升的是声明,没有赋值; function声明的函数要整体提升到代码段的最前面。


<script>
    // 预解析提升:
    // 相当于var a ;
    // 相当于 function fn() {console.log('我是一个函数');}
    //执行代码:
    console.log(a); //undefined   预解析并未提升变量值,所以返回undefined
    var a = 110;//执行到此步 相当于给 变量a赋值110;
    console.log(a);//110

    fn(); //'我是一个函数'
    //浏览器预解析时,函数整体都提升到了最前面
    function fn() {
   
        console.log('我是一个函数');
    }
</script>

控制台打印结果:
在这里插入图片描述

将函数体赋值给变量的情况


<script>
    // 相当于 var g = undefined;
    g(); //Uncaught TypeError: g is not a function  输入错误
    // 加var的变量仅提升声明 不提升赋值,所以此变量的值一开始是undefined
    // g 此时是值为undefined的变量   而不是一个函数function ,所以不可以用g()调用



    // 函数表达式
    // 本质是一个变量, var 用来声明变量
    // 这个变量的值是函数  函数也是一种数据
    var g = function() {
   
        console.log('g....');
    }
</script>

控制台打印结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gWfouUye-1666514841384)(https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/4ded33f22c0941128ce017af86d233cb~tplv-k3u1fbpfcp-watermark.image?)]

2. 声明提升与执行的具体过程:
全局变量提升到页面window最上面, 如果在函数内部的(var声明)局部变量,就提升到函数内部的最前面


<script>
    // 1、最外层预解析提升:

    // var a ;
    // 2、函数整体提升与内部预解析:
    // function fn() {
   
    // var b ;
    // c = 111;
    // console.log(b);
    // console.log('我是一个函数');}


    //3、执行代码:
    console.log(a); //undefined  预解析并未提升变量值,所以返回undefined
    var a = 110; //执行到此步 相当于给 变量a赋值110
    console.log(a); //110

    fn();
    //浏览器预解析时,函数整体都提升到了最前面
    function fn() {
   
        console.log(b); //undefined
        var b = 220; //执行到此步 相当于给 变量b赋值220
        c = 111; //不是var 声明的全局变量  
        console.log(b);
        console.log('我是一个函数');
    }
    console.log(c); //111
</script>

控制台打印结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0bNxYs9w-1666514841385)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c901da9308d249ad853024f4da7ce525~tplv-k3u1fbpfcp-watermark.image?)]

3. 特别注意:
加 var 的变量,仅仅是提升声明;函数提升的不仅只有声明,还有赋值。

三、数据与数据储存(执行的JS代码数据在内存区的分配)

3.1 数据的容器 栈(stack)和 堆(heap)

JS代码是运行在计算机(或者手机等)硬件设备上的,以计算机来说,计算机储存分为RAM内存和ROM外存(也叫硬盘),计算机的RAM内存相当于一个中转站,计算机所需调取数据是从RAM内存中调取,RAM内存的特点是数据传输速度快,而RAM内存的数据又是从ROM外存中调取的,本次重点理解RAM内存中的两个区 栈(stack)、堆(heap)
在这里插入图片描述

3.2 数据的分类

数据可以分为两类:原始类型(也叫:简单数据类型、基本数据类型)、对象Object

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值