var定义的变量为函数作用域:

    1. var nub = 1 //全局作用域(window)
    2. function arr() {
    3. var b = 20 //函数作用域arr
    4. if (b === 20) {
    5. var c = 2 // 函数作用域arr,并不是if块
    6. d = 40 // 全局作用域,未加var定义的变量为全局作用域
    7. }
    8. }

    变量提升
    在代码执行前、解析器会解析代码。

    1. console.log(a)
    2. var a = '输出'
    3. // 结果是undefined 代码执行顺序⬇️
    4. // var a
    5. // console.log(a)
    6. // a = '输出'

    哪怕代码中出现不执行的代码、解析器也会执行解析⬇️

    1. funciton hd() {
    2. if (false) {
    3. var web = '本不应该输出的'
    4. }
    5. console.log(web)
    6. }
    7. // 结果是undefined
    8. // 代码中的web还是被提升了,也还是被定义了。但是并未赋值

    当发生重名的函数时,后者取代前者,并且函数的优先级别大于变量

    1. var a = 1
    2. function a () {}
    3. console.log(a)
    4. // function a(){}
    5. //因为在变量提升的过程中,遇到相同的函数和变量名称不论前后。函数都是第一位,也就是函数是js的一等公民。

    let、const声明、临时死区
    意思就是如果声明的变量在使用之后就会报错,必须在使用之前。
    并且let和const生命的变量不会注册到全局上。而var生命的变量会挂在window上

    1. console.log(a)
    2. let a = 11
    3. // 输出会报错 Cannot access 'a' before initialization at script 1:13"

    let为块级作用域、用let和const生命的变量不会污染的到全局。
    let/const声明的变量存在scope里。而var是存在window里的
    var**letconst的共同点**
    1、函数中是可以访问全局变量的。
    2、作用域内的变量优先使用作用域内的变量。

    块作用域
    var没有块作用域、会影响全局

    1. var i = 99
    2. for (var i = 0; i<5; i++) {
    3. console.log(i)
    4. }
    5. console.log(i)
    6. // 输出5
    7. 因为循环后的i、会影响全局的i

    let和const是块级作用域不会影响全局作用域。
    const**一探究竟**
    const常量在同一个作用域是不可以修改的、但是对象在任何作用域是可以修改的。
    只要不改变引用的内存地址就可以修改const

    1. const ITEM = {}
    2. ITEM.config = 1

    变量冻结
    Object.freeze当用const定义引用类型时、对象内部的参数是可以冻结的。

    1. const list = {
    2. name: 'qihuanran',
    3. age: 12
    4. }
    5. Object.freeze(list) //冻结内部的变量、不允许修改
    6. console.log(list)


    传值和传址
    image.png
    传值是新开一块栈内存,并且赋值一份a
    传址是新开一快内存,并且指向a,a和b共同使用一块堆内存。

    **