你不知道的JavaScript(上)4

137 阅读2分钟

提升

本章的标题特别的简介,就这俩字。我想大家都能想到这是讲关于变量提升问题的

哔哩哔哩等我

    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钻着估计要疯,感谢!

谁知道答案,麻烦指点我一下!