摘自codeburst:JavaScript中的后置声明是什么?

83 阅读3分钟

译者:chaussen

原文链接


JavaScript中的后置声明提前是什么?

提示: 可能跟同学们理解的不太一样。

刚开始接触JavaScript时,大家可能都碰到过_后置声明_这个词。学习这个词的定义之前,让我们先看一个例子。下面我们先创建一个函数再调用:

function cowSays(sound){
  console.log(sound);
}

cowSays('moo');

很明显,调用cowSays函数,并给它一个任意字符串作参数,控制台就会把这个字符串打印出来。在这个例子中, 我们看到的是'moo'这个字符串。

cowSays('moo');
// moo

但如果这个函数没有声明就调用呢?

cowSays('moo');

function cowSays(sound){
  console.log(sound);
}

控制台还是打印出了'moo',这可能有些同学想不到。

cowSays('moo');
// moo

这就是后置声明提前的用例

那么到底是怎么回事呢?通常,后置声明提前可以解释成程序把后面的_声明_移到_代码_的顶部。虽然看起来的确是这样,但我们要理解到底后置声明提前是怎么进行的,这一点很重要。要知道,代码是不可能随意移动的,不可能像变戏法一样就移动到源文件顶部去。实际上是程序在编译阶段把你的函数声明和变量声明加到了内存中去

在上面的例子中,程序编译阶段我们的函数声明已经加到内存中去了,所以即使源代码还没有运行到我们输入的声明语句,仍然可以调用这个函数。

来看一个变量的例子:

变量典型的用法是先声明,再初始化再使用:

var a = 3;
console.log(a);

// 3

但是如果变量在代码最后声明会怎样呢?

a = 3;
console.log(a);
var a;

// 3

看到了吧,上面的例子里打印出来的是3

那么在下面这个例子里,我们在代码最后声明并初始化变量会有什么结果呢?

console.log(a);
var a = 3;

// undefined

嗯,这个例子里我们第一次看到了想不到的结果。原以为程序会打印出来3,但程序却打印出来未定义

为什么呢?因为JavaScript只会把后置的声明提前,而初始化不会提前。

比如说var a = 3;这个语句同时声明并初始化了一个变量,那只有var a;这个声明的部分会被提前。初始化部分a = 3;不会提前,所以不会加载到内存里去。

要记住,如果一个变量声明了却没有初始化值,那它的值就会自动定为未定义。那我们再回过头来看看一开始的例子。下面的代码中,只有var a;部分会提前:

console.log(a);
var a = 3;

// undefined

实际上,上面的代码如果写成下面这样也会产生相同的结果:

var a;
console.log(a);
a = 3;

// undefined


最佳做法

因为后置声明会被提前,最佳的做法就是把所有的变量都声明在其各自作用范围码块的顶部。这样不会产生不想要的结果。我们声明变量时都要尽量初始化值,这可以使代码更清晰,也可以尽量避免未定义的变量。