提升
本章的标题特别的简介,就这俩字。我想大家都能想到这是讲关于变量提升问题的
哔哩哔哩等我
var a = 2;
之前一开始就提到过,这句代码,可能你认为是一个操作,但是JS引擎可不这么认为。其中var a;这句代码扔给编译器,而a = 2;则留给引擎处理。而编译是在代码执行之前,所以这就造成了变量的提升。
console.log(a,b) // undefined unfined
var a = 2;
var b = function(){ //... }
但是还有这么种情况
demo() // 函数正常执行
function demo(){
//...
}
哎哟?啥意思嘛?你上个例子仅仅提升了undefined,这回整个函数都上去了?
区分函数表达式和函数声明是十分有必要的
变量和函数在内的所有声明都会在执行前被提升到顶部。但是。只有声明本身会被提升,而赋值操作和其他运行逻辑都会保留在原地。这也可以解释上面的情况了。
书上总结的很好,我再说一下自己的想法
首先在代码执行之前,都会有一个预编译的过程。这个过程,分四部:
- 创建AO/GO对象
- 变量声明提升,函数表达式声明提升
- 实参形参相统一
- 函数声明提升 ------这一点书上的表达方式不同
由于我上述第四点的存在,所以会有以下情况
foo() // 不会报错,打印1
function foo(){ console.log(1) }
var foo = 123
我的表述是:函数声明会覆盖掉之前已经提升的var foo
书上的观点是函数优先,意思是:函数会优先提升,提升之后呢,再碰到var foo 直接忽略掉了。
两者观点一摸一样,只是表述方式不同,看官随意。
大家如果对我说的预编译四部曲有所疑问,欢迎留言。
我已经提交了,结果想起个重点没和大家分享,如果你对自己变量提升知识方面比较自信,看一下这个demo:
console.log(demo) // undefined
var a = true
if(a){
function demo(){ console.log(1) }
}else{
function demo(){ console.log(2) }
}
GoogleChrome打印的是undefined
safari打印函数体 function(){console.log(2)}
node直接跑js文件 打印undefined
按我掌握的知识来讲,我觉得safari的结果才是正确的。但是GoogleChrome作为前段开发的标配来讲,我也不敢说他是错的,而且node跑出来的结果也是undefined。
这个demo我没有整明白,但是只要有safari的结果,就说明自己掌握的知识没问题,可能是由于浏览器内核或者什么因素造成的这个结果吧。这个问题请教了字节跳动的大佬才用safari试了一下,要不一直在GoogleChrome钻着估计要疯,感谢!