本地Javascript作用域问题

Local Javascript scoping issue

本文关键字:问题 作用域 Javascript 本地      更新时间:2023-09-26

如果我这样做:

var a = 0;
(function () {
    var a = a; //want to make local a = global a
    ++a;
    console.log("fn",a);
})();
console.log(a);​

输出为:

fn NaN
0

为什么自执行函数内部的a变成NaN

我知道如果我这样做的话效果很好:

(function () {
    var b = a;
    ++b;
    console.log("fn",b); // fn 1
})();

但如果我采用第一个版本的方式,它有NaN问题。

为什么会发生这种情况?

var a = a;实际上是var a; a = a;。这意味着在分配时,旧的a已经被新的undefined遮蔽。

避免此类问题的最简单方法是将值作为参数传递:

(function (a) {
    ++a;
    console.log("fn",a);
})(a);

如果a是全局变量,您也可以像woz建议的那样使用var a = window.a;,但由于拥有全局变量通常是个坏主意,因此最好使用参数。

函数表达式中的a变量遮蔽了外部作用域上声明的a变量

它变为NaN,因为在分配中:

var a = a;

右侧的a实际上是指本地范围内的a

变量声明是在函数实际开始执行之前完成的,这通常被称为"提升"。

由于它是同一个变量,所以它保持undefined值,当您尝试将任何数字添加到该值时,它将变为NaN:

console.log(undefined + 0);

在JavaScript中,当前执行上下文(包括变量范围等内容)是在代码开始执行之前建立的。

这对您来说意味着首先分配您的局部变量名。由于提升,函数中任何位置的var语句中的标签在当前执行上下文中被初始化为未定义。(函数语句也在此步骤中初始化。)

接下来,您的代码实际上开始执行。a标签已经在当前执行上下文中保留,因此var a = a;只是将本地a未定义)分配给它自己。

var a = window.a之所以有效,是因为您可以通过直接访问全局作用域来回避作用域问题。然而,这在非浏览器环境(如Node)中不起作用,因为没有window;Node中的全局对象是CCD_ 23。

javascript中有一个变量提升,因此执行过程中的代码如下所示:

(function () {
    var a;
    a = a; //want to make local a = global a
    ++a;
    console.log("fn",a);
})();

因此,首先将局部变量a设为未定义变量,然后将未定义变量分配给变量a