是否可以将变量设置为undefined或将undefined作为参数传递?


304

我对JavaScript undefinednull值有些困惑。

什么是if (!testvar)真正做到?它会测试undefinednull还是undefined

定义变量后,我可以将其清除回undefined(从而删除变量)吗?

我可以undefined作为参数传递吗?例如:

function test(var1, var2, var3) {

}

test("value1", undefined, "value2");

Answers:


513

我对Javascript undefined和null感到有些困惑。

不要困惑null。它通常是有意义的,其行为与带外“ null”,“ nil”或“ None”对象的其他脚本语言的概念类似。

undefined另一方面,是一个怪异的JavaScript怪癖。这是一个单例对象,表示带外值,本质上是第二个相似但不同的对象null。它出现了:

  1. 当您调用的函数参数少于function语句列表中的参数列表时,未传递的参数将设置为undefined。您可以使用以下方法进行测试:

    function dosomething(arg1, arg2) {
        if (arg2===undefined)
        arg2= DEFAULT_VALUE_FOR_ARG2;
        ...
    }

    使用这种方法,你不能告诉之间的区别dosomething(1)dosomething(1, undefined); arg2两者的值相同。如果您需要区分它们,可以看一下arguments.length,但是做这样的可选参数通常不太容易理解。

  2. 当函数没有时return value;,它返回undefined。通常不需要使用这样的返回结果。

  3. 当您通过var a在块中包含一条语句来声明变量但尚未为其分配值时,它就是undefined。同样,您实际上根本不需要依赖它。

  4. 诡异的typeof运算符'undefined'在其操作数是一个不存在的简单变量时返回,而不是引发错误(如尝试引用它时通常会发生的错误)。(您也可以给它一个用括号括起来的简单变量,而不是包含不存在变量的完整表达式。)对此也没有太多用处。

  5. 这是有争议的。当您访问不存在的对象的属性时,不会像其他每种语言一样立即得到错误。相反,您得到一个undefined对象。(然后,当您稍后尝试undefined在脚本中使用该对象时,它将以一种奇怪的方式出错,这比JavaScript马上抛出错误要难得多。

    这通常用于检查属性是否存在:

    if (o.prop!==undefined) // or often as truthiness test, if (o.prop)
       ...do something...

    但是,因为您可以undefined像分配其他任何值一样进行分配:

    o.prop= undefined;

    实际上无法检测到该属性是否可靠存在。最好使用in运算符,该运算符不是原始的Netscape JavaScript版本中的,但现在随处可用:

    if ('prop' in o)
        ...

综上所述, undefined是一个特定于JavaScript的混乱,使所有人感到困惑。除了可选的函数参数外,undefined应避免使用JS没有其他更优雅的机制。它不应该成为语言的一部分。null对于(2)和(3)来说本来很好,并且(4)是一个错误特征,仅在开始时就存在,因为JavaScript没有例外。

什么if (!testvar)实际上做?是否测试未定义和null或只是未定义?

这样的“感实性”对测试检查falseundefinednull0NaN和空字符串。但是在这种情况下,确实是undefined它有关。海事组织,对此应该更明确地说if (testvar!==undefined)

一旦定义了变量,我可以将其清除为未定义(因此删除变量)。

您当然可以分配 undefined,但这不会删除该变量。只有delete object.property操作员才能真正移除物品。

delete实际上是针对属性而不是变量。浏览器将使您远离delete variable,但是这不是一个好主意,并且不能在ECMAScript Fifth Edition的严格模式下使用。如果您想释放对某物的引用,以便可以对其进行垃圾收集,那么通常会说variable= null

可以将undefined传递为参数吗?

是。


10
太棒了。我刚通过JavaScript测试失败:perfectionkills.com/javascript-quiz 稍后,我将重新阅读您的答案并再次尝试测试!
Skilldrick

1
固定,ta。(我不太担心重新分配,因为脚本可以重新定义太多东西,以至于弄乱了一切,所以一般情况下是无法解决的。)
bobince 2010年

2
@bobince undefined是一个单例对象吗?你什么意思?它是一个原始值,而不是对象。
森那维达斯

2
@Hortitude:这就是要点(4)。我一般不会typeof foo=='undefined'; 它倾向于用于(4a)全局嗅探,在这种情况下,我宁愿明确表示并说'foo' in window,或(4b)对undefined-value本身进行测试,在这种情况下,我宁愿可读性和说出foo===undefined。从理论上讲,typeof针对的测试'undefined'可能具有其他构造无法提供的用例:嗅探局部变量的存在。但是实际上,您几乎总是知道哪些变量声明为局部变量。
bobince 2011年

4
带有#2的警告,通常是不带return语句undefined的函数会返回,但是如果该函数是构造函数(由new运算符调用this),尽管没有return语句,它也会返回新对象(构造函数内部的值)。console.log((function (){}()));返回undefinedconsole.log((new function (){}()));返回一个对象。
无用的代码,

18

您不能(应该吗?)将任何东西都定义为未定义,因为变量将不再是未定义的–您只是定义为某种东西。

您不能(应该吗?)传递undefined给函数。如果要传递空值,请null改用。

该语句if(!testvar)检查布尔值的真/假值,该特定值测试是否testvar评估为false。根据定义,null并且undefined都不应该将truefalse评估nullfalse,但JavaScript的评估为,并且如果您尝试评估未定义的变量,则会出错。

要正确测试undefinednull,请使用以下这些:

if(typeof(testvar) === "undefined") { ... }

if(testvar === null) { ... }

1
三重等式也会检查类型,因此不会执行任何类型的强制转换。Douglas Crockford建议不要使用类型强制运算符(==!=)。
Skilldrick

3
您可以将某些内容定义为未定义。var a= undefined。你可以通过fn(undefined)。如果要查找p对象的未定义属性op已定义并设置为的属性之间的区别undefined,则必须使用'p' in o运算符。
bobince 2010年

1
有理由为什么不应该去测试testvar === undefined而不是更复杂的东西typeof(testvar) === "undefined"吗?
ddaa 2010年

4
使用typeof测试未定义变量还有另一个很好的理由:与nullundefined只是简单地是全局对象的属性,并且本身可以重新定义。它仅采用特定的编码样式,并且缺少等号并被undefined默默更改:if (undefined = someVar) {...}
Tim Down

1
@IanGrainger:ECMAScript 5(在所有浏览器的当前版本中实现)主要通过以下方法解决了此问题: undefined全局对象具有不可变属性来,因此它比以前更安全。但是,仍然可以undefined在函数中定义一个可变变量,因此问题并未完全解决。
Tim Down

13

基本区别是undefinednull代表不同的概念。

如果仅null可用,null除非您使用了麻烦的错误捕获功能,否则您将无法确定是否有意将其设置为该值或尚未设置该值:

var a;

a == null; // This is true
a == undefined; // This is true;
a === undefined; // This is true;

但是,如果您有意将值设置为null,则与的严格相等会undefined失败,从而使您可以区分nullundefined值:

var b = null;
b == null; // This is true
b == undefined; // This is true;
b === undefined; // This is false;

在这里查看参考,而不是依靠人们不屑一顾地说垃圾,例如“总之,未定义是JavaScript特有的混乱,使所有人感到困惑”。仅仅因为您感到困惑,并不意味着它是一团糟。

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/undefined

这种行为也是不特定的JavaScript和它完成广义的概念,一个布尔结果可能是truefalse未知(null),没有值(undefined),或出事了(error)。

http://en.wikipedia.org/wiki/未定义值


而且仍然 null可以正常工作。a == nulltrue因为Javascript类型具有强制性。
sleepwalkerfx

11

检查空值的最佳方法是

if ( testVar !== null )
{
    // do action here
}

对于未定义

if ( testVar !== undefined )
{
    // do action here
}

您可以分配一个带有undefined的变量。

testVar = undefined;
//typeof(testVar) will be equal to undefined.

1
检查空值的最佳方法是使用!==,而不是!=
MBO 2010年

6

是的,您可以,因为undefined被定义为undefined。

console.log(
   /*global.*/undefined === window['undefined'] &&
   /*global.*/undefined === (function(){})() &&
   window['undefined']  === (function(){})()
) //true

您的情况:

test("value1", undefined, "value2")

您还可以创建自己的未定义变量:

Object.defineProperty(this, 'u', {value : undefined});
console.log(u); //undefined

5

为了回答您的第一个问题,not运算符(!)将强制将其赋值为布尔值。所以null0falseNaN""(空字符串)都将出现错误。


还有空字符串和NaN(不是数字)
MBO 2010年

undefined不会显示为false,它将引发“未定义”错误。
塔图·乌尔曼嫩

塔图·乌尔曼嫩(Tatu Ulmanen):并非如此。if (undefined) {/* Do stuff*/}因为undefined存在作为全局对象的属性,所以不会给出错误。会产生错误的是类似的东西if (someUndeclaredVariable) {/* Do stuff*/}
Tim Down

2

JavaScript,如何在命令行中将变量设置为undefined:

js在Ubuntu 12.10上的Java附带的javascript命令行终端中,将变量设置为undefined 。

el@defiant ~ $ js

js> typeof boo
"undefined"

js> boo
typein:2: ReferenceError: boo is not defined

js> boo=5
5

js> typeof boo
"number"

js> delete(boo)
true

js> typeof boo
"undefined"

js> boo
typein:7: ReferenceError: boo is not defined

如果您在javascript中将变量设置为undefined:

把它放在myjs.html中:

<html>
<body>
    <script type="text/JavaScript">
        document.write("aliens: " + aliens);
        document.write("typeof aliens: " + (typeof aliens));
        var aliens = "scramble the nimitz";
        document.write("found some aliens: " + (typeof aliens));
        document.write("not sayings its aliens but... " + aliens);
        aliens = undefined;
        document.write("aliens deleted");
        document.write("typeof aliens: " + (typeof aliens));
        document.write("you sure they are gone? " + aliens);
    </script>
</body>
</html>

它打印此:

aliens: undefined
typeof aliens: undefined
found some aliens: string
not sayings its aliens but... scramble the nimitz
aliens deleted
typeof aliens: undefined
you sure they are gone? undefined

警告!将变量设置为undefined时,会将变量设置为另一个变量。如果有一些偷偷摸摸的人在奔跑,undefined = 'rm -rf /';那么每当您将变量设置为undefined时,您都会收到该值。

您可能想知道如何在开始时输出未定义值的外星人并使它仍然运行。这是因为javascript吊起:http : //www.adequatelygoodgood.com/JavaScript-Scoping-and-Hoisting.html


2

尝试这个:

// found on UglifyJS
variable = void 0;

0

for if (something)if (!something)通常用于检查是否已定义某些内容。例如:

if (document.getElementById)

标识符将转换为布尔值,因此undefined被解释为false。当然还有其他值(例如0和”)也被解释为false,但是标识符不应该合理地具有这样的值,或者您很乐意将此类值与undefined相同。

Javascript具有delete可用于删除对象成员的运算符。根据变量的范围(即是否为全局变量),可以将其删除以使其不确定。

没有undefined可以用作未定义文字的关键字。您可以在函数调用中省略参数以使它们变得不确定,但这只能通过向函数发送较少的参数来使用,而不能在中间省略参数。


0

只是为了好玩,这是将“未分配”分配给变量的一种相当安全的方法。为此,需要有人以与随机生成的字符串完全相同的名称添加到Object的原型中。我确定可以改进随机字符串生成器,但是我只是从以下问题中选择了一个:在JavaScript中生成随机字符串/字符

这是通过创建一个新对象并尝试使用一个随机生成的名称访问它的属性来实现的,我们假设该名称将不存在,因此将具有未定义的值。

function GenerateRandomString() {
    var text = "";
    var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

    for (var i = 0; i < 50; i++)
        text += possible.charAt(Math.floor(Math.random() * possible.length));

    return text;
}

var myVar = {}[GenerateRandomString()];
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.