变量提升 又叫 预解释
在JS代码执行之前 对所有的变量进行提前带var 和 function 变量进行前提声明和定义(赋值)
- 声明:声明一个变量 告诉浏览器有一个变量
- 定义: 给变量赋值
- 对于带var 的 进行提前声明 不赋值(变量声明时不赋值 变量的默认值是undefined) 告诉浏览器有这么一个变量
- 带 function 的 进行提前声明 并赋值为函数定义本身 变量提升结束后 代码从上到下执行
- 当执行到function 函数名时 跳过 因为在变量提升阶段就已经完成对变量的赋值的过程 function 函数 不论在声明前使用 还是声明后使用 都是函数本身
JS的运行机制(栈内存):作用域
作用域是JS运行的环境 另一个功能是保存基本数据类型
- 全局作用域 当页面打开时 首先形成一个全局作用域 在执行全局作用域中的代码 是window
- 私有作用域 当函数执行时 形成一个函数作用域 这个作用域用来保存函数中的基本数据类型 同时执行函数代码
- 块级作用域 (类似私有作用域 ES6)
js 运行过程
- 在JS代码执行之前 浏览器会开辟一个全局作用域 然后执行变量提升 变量提升后 代码从上到下执行
- 在执行时 若遇到基本数据类型 就在作用域中存储该基本数据类型
- 在执行时 若遇到引用数据类型 刘篮球会再分配一个堆内存 然后把引用数据类型的内容存储到堆内存中 再把这个堆内存的地址赋值给变量(此时这个地址存储在作用域内存中)
- 遇到函数执行时 会经历以下步骤: - 浏览器会开辟一个私有作用域 - 形参赋值 把执行时的实参赋值给函数形参变量 - 私有作用域中变量提升 - 函数代码从上到下执行
私有变量和全局变量
- 私有变量 函数的形参以及在函数私有作用域中声明的变量
- 全局变量 在全局作用域中声明的变量 预解释只发生在当前作用域 若函数不执行 函数中的变量不会进行变量提升
重复声明问题
- 同名便令只会声明一次 代表的值就是最后一次的值
- 变量提升时 function 的优先级高于普通变量
- 若变量名和函数名同名 在执行到变量的赋值语句之前时 这个名字代表函数 但是当执行过变量赋值语句后
##变量提升细节
- 等号右侧不会进行变量提升 即使右侧时函数也不会进行变量提升
- 条件语句的变量不管条件是否成立 都会参与当前作用域中的变量提升
- 函数中 return 下面的代码虽然不执行 但是会进行函数作用域中的变量提升
- 函数的返回值不参与变量提升 return右面的不会参与变量提升
带var 和 不带 var的区别
- 在全局作用域中 用var 和 function声明的变量 也相当于给window上添加一个同名属性
- 不带var 的 不会参与变量提升