js 中的变量提升

2017-08-01  本文已影响24人  McDu
  1. 当浏览器加载 HTML 页面时,首先会提供一个全局的执行环境,称为全局作用域,浏览器中是 window(既是一个窗口对象,也是全局作用域),后端环境中是 global。
  2. 对象是引用类型,修改对象的属性值时,先通过地址找到堆内存,然后把堆内存中的值改变。比如把之前的 obj.age = 2 改为 obj.age = 4。
  3. 对于函数,函数是对象数据类型,首先开辟一个内存空间(里面存的是字符串形式的函数体),函数名存储一个地址,代表当前函数本身。

变量提升 (预解释)

  1. 定义:在当前的作用域中,js 代码执行之前,浏览器首先会默认把所有带 var 或 function 的进行提前的声明或定义。
  2. 预解释只发生在当前的作用域中,比如,开始只对 window 下的进行解释,只有函数执行的时候才对函数中的声明进行解释。
  3. 栈内存:用来提供一个 js 代码执行的环境 -> 作用域(全局、私有)
  4. 堆内存:用来存储引用数据类型的值 -> 对象存储的是属性名称和属性值,函数存储的是代码字符串。
  5. 变量预解释时只是声明,函数预解释时声明和定义已完成。
  6. 函数执行时,会形成一个私有作用域,创建私有作用域就创建了一个栈内存,如果有形参,先给形参赋值。
  7. 闭包是一种机制,函数执行时形成一个私有作用域,保护函数内部的变量不被外界影响。
  8. 预解释时,不管 if 条件是否成立,都要把带 var 的变量提前声明。
  9. 预解释只预解释等号左边的变量,右边的值不参与。
fn()  // ->  TypeError :fn is not a function 
var fn = function (){ };

fn2()   // -> "keyi"
function fn2(){
  console.log("keyi")
}
  1. 自执行函数在全局作用域下不预解释,当代码执行到时定义和执行一起完成。
  2. 函数体中 return 下面的代码虽然不再执行,但 return 后面的代码仍需预解释。return 后面跟的都是值,不进行预解释。
  3. ES5 中,在同一个作用域,如果变量名和函数名相同,最终只能保留一个。
fun();        // -> 2
function fun(){console.log(1)};      //  window 声明+定义,开辟一个堆内存 1
fun();       // -> 2
var fun = 100;           // fun = 100 
function fun(){console.log(2)};     // fun 已经声明过了,放弃堆内存1 ,转向堆内存2.
fun();     // 这里不执行,100() 不是一个函数
  1. 函数定义的地方就是上级作用域,跟函数执行的地方无关。
上一篇下一篇

猜你喜欢

热点阅读