javascript中的变量和函数提升

版权声明:欢迎转载,转载请注明原始出处 https://blog.csdn.net/xiaomingelv/article/details/90738623

提到代码的执行顺序,在不考虑异步回调的情况下,有些开发者可能会认为,同步的js代码的执行顺序跟代码编写的顺序是一致的,即从上往下一行一行的执行。这种想法,严格上只能说是大致正确。

从编译器的角度来说,js引擎在解析我们代码的时候,首先会找到所有的变量声明,并且把他们关联到对应的作用域上。简单来说,编译器会首先处理所有的声明,包括函数和变量,这个过程被称为提升

变量提升

首先,我们通过下面的代码来了解一下变量提升

a='测试';
var a;
console.log(a);//输出‘测试’

对于初学者,可能会觉得此时应该输出undefined,但事实上并不是,因为发生了变量提升,所有的变量声明都会被提升到作用域的最顶端,所有上面的代码经过解析之后会整理为下面这个样子

var a;
a='测试';
console.log(a);

这两段代码的输出结果是一致的,有一点必须注意的是,变量提升仅仅对对变量的声明进行提升,变量的赋值操作并不会受到影响,仍然会保留在原处,我们可以看下面这段代码的输出,a输出了undefined,说明仅仅是被声明,但是未被赋值

console.log(a);//输出undefined
var a='测试';

函数提升

和变量提升相似,对于函数的声明也会有相应的提升,我们看下面的代码

test();//输出“测试”
function test(){
    console.log('测试');
}

我们可以看到虽然函数在执行之后才声明,但是并不影响函数的使用,函数提升有一点必须注意的是,对于函数的声明会被提升,但是,函数表达式却不会,我们可以看下面的代码

test();
var test=function(){
    console.log('测试');
}

我们会发现,这段代码不仅不会输出,甚至还报错了

原因在于,函数表达式并不会被提升,此处只发生了变量提升,所以上面的代码事实上被解析为下面的样子

var test;
test();
test=function(){
    console.log('测试');
}

执行test函数时,test仍未undefined,将它当成函数执行,自然就会报类型错误。

对比

我们现在知道,变量和函数声明都会发生提升,但如果同时发生了,并且变量名还重复了,那么会发生什么呢,我们看下面的代码

test();//输出“测试2”
var test=function(){
    console.log('测试1');
};

function test(){
    console.log('测试2')
}
test();//输出“测试1”

不了解提升规则的话可能会有点懵,但如果了解提升规则,就会明白这样输出是有道理的,对于变量和函数声明同时存在提升,函数会首先被提升,其次才是变量,所以上面的代码其实跟下面的代码是相等的

function test(){
    console.log('测试2')
}
var test;
test();//输出“测试2”
test=function(){
    console.log('测试1');
};
test();//输出“测试1”

这样的话是不是就好理解很多了,但还是要稍微做一下解释,对于var test这个声明,事实上是重复声明,所以会被忽略掉,虽然var test被忽略了,但是由于共用了同一个test变量,所以后续对于test的修改,确实会覆盖掉先前的声明,所以发生上面的输出,也就不意外了

结语

虽然上述的示例代码在实际开发过程会很少出现,但是极端情况对于了解代码的本质也确实一个很好的选择。但是还是要说一句,不管在什么情况下,像最后一个示例一样重复定义一个变量都是一种极度糟糕的做法,会让代码变的很难理解。另外,由于变量提升的出现,为了使代码更好维护,约定俗成的做法是将所有的变量声明都放在作用域的最顶端,这样可以减少误解,增加代码的可读性,虽然这不是强制性的,但这样做的好处确实也是很明显的,最后祝大家coding愉快

猜你喜欢

转载自blog.csdn.net/xiaomingelv/article/details/90738623