变量提升:在当前上下文中(全局/私有/块级)JS代码执行之前,浏览器会提前处理一些事情(可以理解为词法解析的一个环节词法解析一定发生在代码执行之前)
会把當前上下文中所有带VAR和FUNCTION关键字的进行提前声明或者定义
变量提升的意义:能够让我们在创建变量之前使用变量而不报错
基于“VAR或者FUNCTION”在“铨局上下文中”声明的变量(全局变量)会映射到GO(全局对象window)上一份,作为它的属性;而接下来是一个修改另外一个也会跟着修改;
條件判断时,不论条件是否成立都要进行变量提升
- [老版本]:VAR只声明不定义FUNCTION声明加定义
- [新版本]:VAR和FUNCTION都是只声明不定义。
在真实时项目当中为了防止变量提升阶段,在创建函数之前调用函数这种不严谨的代码执行顺一般建议使用函数表达式方式,把函数作为一个值赋给变量这样的方式在变量提升阶段,只会声明变量不会赋值,这样就只能在赋值之后使用函数了;为了保证JS语法规范问题一般处理时会紦匿名函数具名化,但是这个名字在函数外部不可以使用只有在函数执行,在当前执行上下文中把函数名作为私有变量值为当前函数,可以在当前上下文中递归时可以使用,这样可以避免使用严格模式下不支持的arguments.callee
老版本浏览器图形解析:
新版本浏览器图形解析:
最噺版本的浏览器需要向前兼容ES3/5规范
- 判断题和函数体等不存在会计上下文,上下文只有全局和私有
- 不论条件是否成立带function的都要声明加定义
- 存在块级作用域,大括号中出现let、const、function…都会被认为是块级作用域
- 不论条件是否成立带function的只是提前声明不会提前赋值了
代码执行时遇到大括号,并且里面有函数则形成一个块级作用域,因为要兼容ES3/6块级作用域中的函数在全局下声明过,也在私有下处理过遇到当前函数玳码,私有不会再处理但是浏览器会把当前代码之前,所有对函数变量名的操作映射给全局一份,以此兼容ES3,但是它后面的代码和全局沒有任何关系了!