关于var声明的JavaScript行为解释

关于var声明的JavaScript行为解释,javascript,syntax,behavior,keyword,strict,Javascript,Syntax,Behavior,Keyword,Strict,我有以下代码: "use strict"; function isDefined(variable) { return (typeof (window[variable]) === "undefined") ? false : true; } try { isDefined(isTrue); } catch (ex) { var isTrue = false; } isTrue = true; 有人能给我解释一下为什么当我删除关键字“var”时会抛出异常,但当它

我有以下代码:

"use strict";

function isDefined(variable)
{
    return (typeof (window[variable]) === "undefined") ? false : true;
} 

try
{
    isDefined(isTrue);
}
catch (ex)
{
    var isTrue = false;
}

isTrue = true;

有人能给我解释一下为什么当我删除关键字“var”时会抛出异常,但当它存在时会将其视为未定义的异常吗?

在严格模式下运行时,不允许访问以前未声明的变量。因此,必须先声明
isTrue
,然后才能访问它。因此,如果您删除它前面的
var
,并且它没有在其他地方声明,那么这将是一个错误

引述:

首先,严格模式使得不可能意外地创建全局 变量。在普通JavaScript中,在赋值中错误键入变量 在全局对象上创建新属性并继续“工作” (尽管将来可能会失败:在现代JavaScript中很可能)。 会意外创建全局变量的赋值 在严格模式下抛出:


你的问题中关于
未定义的部分要复杂一点。由于变量提升,编译器将变量声明提升到其声明的作用域的顶部,因此使用
var
语句的代码相当于:

var isTrue;
try
{
    isDefined(isTrue);
}
catch (ex)
{
    isTrue = false;
}

isTrue = true;
因此,当您调用
isDefined(isTrue)
时,
isTrue
的值是
undeffined
。它已声明,但未初始化,因此其值为
未定义
。当您没有
var
语句时,在严格模式下对
isTrue
的任何引用都是错误的,因为它尚未声明

如果您只想知道某个变量是否有值,只需执行以下操作:

if (typeof isTrue != "undefined") {
    // whatever code here when it is defined
}
或者,如果您只是想确保它有一个值(如果尚未初始化),则可以执行以下操作:

if (typeof isTrue == "undefined") {
    var isTrue = false;
}

在严格模式下运行时,不允许访问以前未声明的变量。因此,必须先声明
isTrue
,然后才能访问它。因此,如果您删除它前面的
var
,并且它没有在其他地方声明,那么这将是一个错误

引述:

首先,严格模式使得不可能意外地创建全局 变量。在普通JavaScript中,在赋值中错误键入变量 在全局对象上创建新属性并继续“工作” (尽管将来可能会失败:在现代JavaScript中很可能)。 会意外创建全局变量的赋值 在严格模式下抛出:


你的问题中关于
未定义的部分要复杂一点。由于变量提升,编译器将变量声明提升到其声明的作用域的顶部,因此使用
var
语句的代码相当于:

var isTrue;
try
{
    isDefined(isTrue);
}
catch (ex)
{
    isTrue = false;
}

isTrue = true;
因此,当您调用
isDefined(isTrue)
时,
isTrue
的值是
undeffined
。它已声明,但未初始化,因此其值为
未定义
。当您没有
var
语句时,在严格模式下对
isTrue
的任何引用都是错误的,因为它尚未声明

如果您只想知道某个变量是否有值,只需执行以下操作:

if (typeof isTrue != "undefined") {
    // whatever code here when it is defined
}
或者,如果您只是想确保它有一个值(如果尚未初始化),则可以执行以下操作:

if (typeof isTrue == "undefined") {
    var isTrue = false;
}

“因为变量提升,编译器将变量声明提升到其声明的范围的顶部”;这是否适用于所有尊重ECMA5的浏览器?使用此代码在旧浏览器上会发生什么?@RandallFlagg-highting一直是javascript的一部分-它在ECMA5中并不新鲜,因此所有浏览器都执行变量提升。严格模式的不同之处在于,分配给未声明的变量是一个错误,而在较旧的浏览器中,它只是自动创建一个同名的全局变量。“因为变量提升,编译器将变量声明提升到其声明的作用域的顶部”;这是否适用于所有尊重ECMA5的浏览器?使用此代码在旧浏览器上会发生什么?@RandallFlagg-highting一直是javascript的一部分-它在ECMA5中并不新鲜,因此所有浏览器都执行变量提升。严格模式的区别在于,分配给未声明的变量是一个错误,而在旧浏览器中,它只是自动创建一个同名的全局变量。您可能需要考虑两件事:
return typeof window[variable]!='未定义'
就足够了,isDefined的有效签名是
isDefined(string)
,这意味着
isDefined('isTrue')
可以获得您似乎期望的行为(
window[undefined]
window[true]
window[false]
没有意义).您可能需要考虑两件事:
returntypeof window[variable]!='未定义'
就足够了,isDefined的有效签名是
isDefined(string)
,这意味着
isDefined('isTrue')
可以获得您似乎期望的行为(
window[undefined]
window[true]
window[false]
没有意义)。