码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • JS预解析/编译(变量提升):var(仅声明,无赋值)、function变量 创建作用域


    目录

    声明前访问

    不报错

    function:声明+赋值

    除了自执行函数IIFE(隔绝外部作用域),箭头函数(无function)

    var:声明不赋值

    报错

    let 、const、calss :声明不赋值,暂时性死区访问

    不带var:无提升,is not defined

    var a=b=1  等价于var a=1;b=1

    变量重复声明

    可重复声明

    无var

    var、function:只提升一次

    不允许重复声明:let、const,SyntaxError

    function和var重名/共用一个标识名

    访问变量时机

    var声明前:undefined

    var声明后:js用到变量时才赋值,可能覆盖

    let、const 、class:块级作用域

    暂时性死区:作用域/使用起点~变量声明

    顶级作用域

    function和有无var

    浏览器环境:在全局对象window上创建属性

    包括块作用域{ }

    不会在全局对象上创建属性:

    node.js环境:全局对象global

    strict严格模式:不允许无var声明,不允许挂载window,this为undefined

    let 不会在全局对象this上创建属性

    函数作用域:(有无var、let、const)局部变量,外部不可访问

    内部作用域优先级高于外部作用域

    自执行函数IIFE::特殊原因--IIFE 函数具备自己的作用域

    内部:变量提升

    外部:不会函数提升

     修改函数名的值无效

    *编译

    分词/词法分析:分解(var a=2=> var,a,=,2)

    解析/语法分析:词法数组=>程序语法 结构的“抽象语法树”(a->2)(Abstract Syntax Tree,AST)

    代码生成:将 AST 转换为可执行代码


    声明 declare(值默认undefined):声明存在

    定义 defined(赋值操作)

    当栈内存作用域形成时,JS执行前,声明[,赋值]提升到代码块的顶部

    1. console.log(a)//undefined
    2. if(false){
    3. var a = 'a'
    4. }

    声明前访问

    不报错

    function:声明+赋值

    除了自执行函数IIFE(隔绝外部作用域),箭头函数(无function)

    var:声明不赋值

    报错

    let 、const、calss :声明不赋值,暂时性死区访问

    不带var:无提升,is not defined

    var a=b=1  等价于var a=1;b=1

    变量重复声明

    可重复声明

    无var

    1. function a(b){
    2.   console.log(b);  
    3. }
    4. a(45);
    5. // 等价于
    6. function a(b){
    7. b;
    8.   console.log(b);  
    9. }
    10. a(45);

    var、function:只提升一次

    1. var a = 1;
    2. function foo(a) {
    3. console.log(a)
    4. var a
    5. console.log(a)
    6. }
    7. foo(a);
    8. // 输出 1 1

    不允许重复声明:let、const,SyntaxError

    1. let x = 1;
    2. {
    3. var x = 2; // 重复声明的 SyntaxError
    4. }

    function和var重名/共用一个标识名

    访问变量时机

    var声明前:undefined

    1. console.log(a);
    2. var a=1;
    3. function a(){
    4. console.log(1);
    5. }
    6. // 或
    7. console.log(a);
    8. function a(){
    9. console.log(1);
    10. }
    11. var a=1;
    12. // 输出都是: ƒ a(){ console.log(1);}

    var声明后:js用到变量时才赋值,可能覆盖

    1. //1.getName 声明不赋值
    2. var getName = function (){
    3. console.log(4)
    4. }
    5. //2.getName=....log(5) 声明+赋值
    6. function getName() {
    7. console.log(5)
    8. }
    9. //3.getName=....log(4)var变量在使用到时赋值
    10. getName()//4
    11. var a=1;
    12. function a(){
    13. console.log(1);
    14. }
    15. console.log(a);
    16. //或
    17. function a(){
    18. console.log(1);
    19. }
    20. var a=1;
    21. console.log(a);
    22. // 输出都是: 1

    let、const 、class:块级作用域

    在类的方法中,this 关键字指向当前实例,而不是指向全局对象。

    暂时性死区:作用域/使用起点~变量声明

    “暂时性”区:这个区域取决于代码执行的时间点,而不是代码编写的顺序。

    1. {
    2. // 暂时性死区始于作用域开头
    3. const func = () => console.log(letVar); //
    4. // 在暂时性死区内访问 letVar 会抛出 `ReferenceError`
    5. let letVar; // 暂时性死区结束(对 letVar 而言)
    6. func(); // 在暂时性死区外调用,会输出 undefined
    7. }

    用 let、const 或 class 声明的变量可以称其从代码块的开始一直到代码执行到变量声明的位置前,都处于一个“暂时性死区”(Temporal dead zone,TDZ)中。

    当变量处于暂时性死区之中时,其尚未被初始化,并且任何访问其的尝试都将导致抛出 ReferenceError。

    当代码执行到变量被声明的位置时,变量会被初始化为一个值。如果变量声明中未指定初始值,则变量将被初始化为 undefined。

    这与 var 声明的变量不同,如果在声明位置前访问 var 声明的变量会返回 undefined。

    1. {
    2. // 暂时性死区始于作用域开头
    3. console.log(bar); // undefined
    4. console.log(foo); // ReferenceError: Cannot access 'foo' before initialization
    5. var bar = 1;
    6. let foo = 2; // 暂时性死区结束(对 foo 而言)
    7. }

    顶级作用域

    挂载this实验时,一定要记得刷新环境,否则还挂在window上

    MDN的浏览器环境,var不会挂载到this,但function,无var会挂载

    function和有无var

    浏览器环境:在全局对象window上创建属性

    1. var a='a'
    2. b='b'
    3. function c(){}
    4. console.log(this.a,this.b,this.c)//a b c(){}
    包括块作用域{ }
    1. if(true){
    2. var a = 'a'
    3. }
    4. console.log(this.a)//a

    不会在全局对象上创建属性:

    node.js环境:全局对象global

    Node.js 使用了 CommonJS 模块系统,每个模块都被封装在一个函数中,这样就避免了全局命名空间的污染。

    Node.js 中的每个文件都被视为一个模块,每个模块都有其自己的作用域。

    当你在 Node.js 模块中使用 var 声明变量时,该变量仅在该模块内部可见。

    strict严格模式:不允许无var声明,不允许挂载window,this为undefined
    1. "use strict";
    2. console.log(this)//undefined
    3. b='b'//b is not defined ,执行到此就会报错,不允许赋值
    4. c //c is not defined ,执行到此就会报错
    5. var a='a'
    6. function fun(){}
    7. console.log(this.a,window.fun)
    8. // Cannot read properties of undefined (reading 'a')
    9. // undefined

    let 不会在全局对象this上创建属性

    1. x = "无var";
    2. let y = "let";
    3. var z="var"
    4. function fun(){}
    5. console.log(this.fun); // ()=>{}
    6. console.log(this.x); // 无var
    7. console.log(this.y); // undefined
    8. console.log(this.z); // undefined(受限浏览器环境,如MDN)/var(正常浏览器环境,如菜鸟教程)

    函数作用域:(有无var、let、const)局部变量,外部不可访问

    1. function fun(){
    2. x = "无var";
    3. let y = "let";
    4. var z="var"
    5. }
    6. console.log(x); // x is not defined
    7. console.log(y); // y is not defined
    8. console.log(z); // z is not defined
    9. console.log(this.x); // undefined
    10. console.log(this.y); // undefined
    11. console.log(this.z); // undefined

    内部作用域优先级高于外部作用域

    1. // 1
    2. console.log(a,b)//undefined; b is not defined
    3. var a =12,b ='林一一'
    4. function foo(){
    5. // 2
    6. console.log(a, b)
    7. // 3
    8. var a = b =13
    9. console.log(a, b)
    10. }
    11. foo()
    12. console.log(a, b)
    13. /* 输出:
    14. undefined undefined
    15. undefined "林一一"
    16. 13 13
    17. 12 13
    18. */

    1. 1处的 a, b 其实就是 window下面的属性为 undefined。
    2. 在函数内部由于变量提升机制 a带 var 一开始就是 undefined,b不带var 将向上级作用域查找,找到全局作用域下的林一一所以2处打印出来的就是 undefined "林一一"。
    3. 随后 a =13,window.b =13,即原来 b='林一一' 变成了 b=13,打印出13, 13,
    4. 最后第4处打印处12, 13。

    自执行函数IIFE::特殊原因--IIFE 函数具备自己的作用域

    内部:变量提升

    1. var a = 'a';
    2. (function(){
    3. console.log(a);
    4. var a;
    5. })(a);
    6. //undefined
    1. var a = 10;
    2. console.log(window.a);
    3. (function () {
    4. console.log(a)
    5. a = 5
    6. console.log(window.a)
    7. var a = 20;
    8. console.log(a)
    9. })()
    10. //10 undefined 10 20

    外部:不会函数提升

    1. var a = 10;
    2. (function c(){
    3. })()
    4. console.log(c)
    5. // Uncaught ReferenceError: c is not defined

     修改函数名的值无效

    1. var a = 10;
    2. (function a(){
    3. console.log(a)
    4. a = 20
    5. console.log(a)
    6. })()
    7. // ƒ a(){a = 20 console.log(a)} ƒ a(){a = 20 console.log(a)}

    参考链接:彻底解决 JS 变量提升| 一题一图,超详细包教包会😉 - 掘金

    JS 扫盲:浅淡JavaScript运行机制和面试题 - 掘金

    *编译

    分词/词法分析:分解(var a=2=> var,a,=,2)

    解析/语法分析:词法数组=>程序语法 结构的“抽象语法树”(a->2)(Abstract Syntax Tree,AST)

    代码生成:将 AST 转换为可执行代码

  • 相关阅读:
    .NET 7 AOT 的使用以及 .NET 与 Go 互相调用
    ClickHouse面向列的数据库管理系统(原理简略理解)
    每次遇到sass 总要出问题,yarn不行,用cnpm i 就顺利了
    JavaScript原生
    Lazada双11大促玩法规则解读,2022备战清单来袭!
    【Java Web】Spring整合Kafka
    『python爬虫』xpath变化导致无法找到指定元素(持续更新中~)
    【C】想练习C语言?通讯录的实现了解一下
    《缓冲区的理解》
    web环境实现一键式安装启动
  • 原文地址:https://blog.csdn.net/qq_28838891/article/details/133053257
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号