10

首先,让我们看一下代码。

var a=0;
b=1;
document.write(a);
function run(){
    document.write(b);
    var b=1;
}
run();

我认为结果是。01但实际上,结果是0undefined

然后我修改这段代码。

var a=0;
b=1;
document.write(a);
function run(){
    document.write(this.b); //or document.write(window.b)
    var b=1;
}
run();

是的,这次它按预期运行。01. 我无法理解,为什么?

更有趣的是,我再次修改了代码。

var a=0;
b=1;
document.write(a);
function run(){
    document.write(b);
    //var b=1;       //I comment this line
}
run();

结果是 01。

那么,有人可以解释一下吗?

感谢您分享您的观点。我简化了这段代码

b=1;
function run(){
    console.log(b); //1
}

二:

b=1;
function run(){
    var b=2;
    console.log(b); //2
}

三:

b=1;
function run(){
    console.log(b); //undefined
    var b=2;
}
4

4 回答 4

17

当您在函数中引用变量时,JS 首先检查该变量是否在当前范围内(即在该函数内)声明。如果未找到,它将在包含范围内查找。如果仍然没有找到,它会在下一个作用域中查找,依此类推,直到最终到达全局作用域。(请记住,您可以将函数嵌套在彼此内部,这就是您获得多个级别的包含范围的方式,尽管您的示例当然不会这样做。)

该声明:

b=1;

without var声明了一个可以在任何函数中访问的全局变量,除了在你的第一个函数中你还声明一个 local b。这称为变量阴影

“但是”,你说,“我声明本地b 之后 document.write(b)”。在这里,您遇到了“提升”声明。JS 解释器将在函数中任何位置声明的变量视为在函数顶部声明的变量(即,它被“提升”到顶部),但是,任何值赋值都发生在适当的位置。所以你的第一个函数实际上是这样执行的:

function run(){
    var b;              // defaults to undefined
    document.write(b);  // write value of local b
    b=1;                // set value of local b
}

在你使用的第二个函数this.b中,你会发现this引用window和全局变量本质上是 的属性window。因此,您正在访问全局b并忽略本地。

在您的第三个函数中,您根本没有声明本地函数b,因此它引用了全局函数。

于 2012-08-15T02:30:33.597 回答
3

当您编写 时b = 1,您正在全局对象中创建一个属性。
在一个普通的函数中,b会引用这个全局的。

由于您的函数包含var b;,b函数内指的是局部变量。(var语句在整个函数中创建局部变量,无论在哪里var)。但是,语句 ( )
的可执行部分仅在该点执行。varb = 1

于 2012-08-15T02:10:58.090 回答
3

var 指令是在预执行阶段处理的,在b之前成为局部变量document.write(b);,所以当时bundefined

注意:为变量赋值是在执行时,所以你可以想象你的代码如下所示。

function run(){
    document.write(b);
    var b=1;
}

是相同的:

function run(){
    var b;
    document.write(b);
    b=1;
}

补充:

这就是为什么将每个 var 定义放在函数顶部是一种好习惯的原因。

于 2012-08-15T02:16:40.773 回答
0

这段代码对我来说很好

  if(var_name === "undefined"){
     alert(var_name+' : undefined');
   }
于 2017-08-02T10:42:27.213 回答