4

我知道 JavaScript 将所有变量声明移动到函数的顶部。但是,我在下面的两个 console.log() 中都期望得到相同的结果。但是,我在第一种情况下得到 NaN,在第二种情况下得到 4。

有人可以解释一下吗?我知道在 StackOverflow 上已经提出并回答了类似的问题,但这个问题与函数定义有关。例如,JavaScript 是否将函数变量移动到变量声明的末尾?

var doB = function() { return a+1};
var b = a+1;
var a = 3;
console.log(b); // NaN
console.log(doB()); // 4
4

4 回答 4

5

由于提升,这就是您的代码在技术上的样子:

var doB, b, a;
doB = function() {
    return a+1;
};
b = a + 1;
a = 3;
console.log(b); // NaN
console.log(doB()); // 4

因为代码是从上到下执行的,当b被初始化为时a + 1a还没有初始化为任何东西(它是undefined)。所以真的,b尝试设置为undefined + 1,即NaN

于 2013-05-04T00:02:26.260 回答
2

在变量被提升之后,你的代码基本上是这样的:

var doB;
var a;
var b;

doB = function() {
    return a + 1
};

b = a + 1;
a = 3;

console.log(b); // NaN
console.log(doB()); // 4

由于a在定义时尚未定义b,b设置为NaN, as undefined + 1 === NaN

a是在函数的范围内,所以当你调用它时,它a的值已经是3.

于 2013-05-04T00:02:41.150 回答
2

JavaScript 范围

我希望使用我目前知道的最正确的术语,我也知道它并不完全正确。我不是任何 javascript 专家,但您所问的这个问题与JavaScript Scope有关。你可以找到很多关于这个主题的文章,也可以找到一些关于 SO 的问答,就像我在示例中找到的一样

一步步

我将尝试逐行重现您的 snipnet 是什么。如果您在某处注意到错误的术语,请发表评论,我喜欢随时学习:D

1号线

var doB = function() { return a+1};

方法

在当前作用域上存储一个名为“doB”的变量,将其内容分配给匿名函数。

所以...

a暂时没关系。


2号线

var b = a+1;

方法

存储一个b在当前范围内命名的变量,将其内容分配给一个new Integer(1)除了变量a

所以...

此时aundefined因为它没有在当前范围内声明,其他范围也不能从这个范围内访问。运算undefined + a等于NaNa被赋值NaN为值。


3号线

var a = 3;

方法

存储a在当前范围内命名的变量,将其内容分配给new Integer(3)

所以...

现在我们有一个a存储整数的变量。


第 4 行

console.log(b);

输出NaN,因为b实际上是NaN.


第 5 行

console.log( doB() );

方法

使用不带参数调用函数console.log的返回值doB作为第一个参数调用函数。

所以...

doB被调用并返回:a+1

意思是

new Integer(1)除了变量a. a不存在于函数本地范围内,但存在于函数内可访问的范围内。该值是从那里获取的,实际上是3. 控制台输出4

于 2013-05-04T00:40:31.977 回答
0

a当您尝试1在分配给它时添加它时未定义b

var b = undefined+1; // = NaN
于 2013-05-04T00:01:12.940 回答