JS代码执行的预处理机制“变量提升”

2021-08-02  本文已影响0人  小生菜呢

在“当前上下文”中,代码执行之前、浏览器首先会把所有带var/function关键字的进行提前声明或者定义:

带var的只是提前声明
带function的,声明+定义(赋值)都完成了

总结几点:

举例说明:

1、

console.log(a) // undefined  变量提升 var a;然后才是代码执行,a只声明没定义,所以是undefined
var a = 12
console.log(b) // Uncaught ReferenceError: Cannot access 'b' before initialization
let b = 12 // 上一句报错,这里不执行了

2、

console.log(fn) 
function fn() {
  console.log(1)
}
console.log(fn) 
var fn = 12
console.log(fn) 
function fn() {
  console.log(2)
}
console.log(fn) 
image.png

1、函数自上而下执行
2、遇到带var和function的要变量提升(且基于var和function声明的而变量存在GO中,)
3、var 只声明,function声明+定义
4、变量提升开始:
function fn(){console.log(1)}
此时GO中存储的是:
function fn : 0x001(函数的堆内存)
5、var fn = 12
6、此时GO中存的是:
function fn : 0x001(函数的堆内存)
var fn
但是fn已经声明过了,GO是一个对象,不允许重复声明变量,所以GO中还是只有一个fn
function fn : 0x001(函数的堆内存)
7、再次遇到function fn(){console.log(2)}
同理fn已经声明过了,不再重复声明,但是函数却不同,所以重新创建一个堆内存:0x002
8、到此变量提升易操作完毕,GO中存储的是:
fn : 0x002

9、变量提升结束,代码开始执行
第一个console.log(fn) :fn指向的地址是0x002 也就是 函数 fn(){console,log(2)}
10、第二个console.log(fn) 同上:fn指向的地址是0x002 也就是 函数 fn(){console,log(2)}
11、var fn = 12 被重新赋值为12
12、所以后边两个console的值都是12


image.png

3、

fn() // 1
function fn() {
  console.log(1)
}
fn() // 1

因为变量提升机制,导致可以在创建函数的代码之前使用函数,这样逻辑就比较松散,真是项目中推荐使用“函数表达式”,把一个函数作为值,赋值给一个变量

比如:

const fn = function (){
  console.log(1)
}

4、

console.log(a) // undefined
if(!('a' in window)) {
  var a = 12
}
console.log(a) // undefined

不论判断条件是否成立,都要变量提升

代码执行:v变脸提升:var a -->window.a
'a' in window:检测‘a’是否是window的属性
‘a’是widow的属性,再取反是false
所以判断不成立
a没有赋值
最后输出a还是undefined
注意:'a'字符串a in window 是检测这个属性名是否在window中的属性‘

a in window 是检测a的值是否是window的属性,a没复制,它的值是undefined,undefined肯定不是window的属性

上一篇 下一篇

猜你喜欢

热点阅读