330

我对 JavaScriptundefinednull价值观有点困惑。

实际上是做什么的if (!testvar)?它是否测试undefinedandnull或 just undefined

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

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

function test(var1, var2, var3) {

}

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

10 回答 10

553

我对 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 特有的一团乱麻,让每个人都感到困惑。除了可选的函数参数,JS 没有其他更优雅的机制,undefined应该避免。它不应该成为语言的一部分;null对于 (2) 和 (3) 本来可以正常工作的,而 (4) 是一个错误功能,它只存在是因为一开始 JavaScript 没有例外。

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

这样的“真实性”测试检查false, undefined, null,0NaN空字符串。但是在这种情况下,是的,它确实是undefined它所关心的。IMO,它应该更明确地说if (testvar!==undefined)

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

您当然可以分配undefined给它,但这不会删除变量。只有delete object.property操作员才能真正删除东西。

delete实际上是针对属性而不是变量本身。浏览器可以让你直接使用delete variable,但这不是一个好主意,并且在 ECMAScript 第五版的严格模式下不起作用。如果您想释放对某事物的引用以便对其进行垃圾收集,则更常见的说法是variable= null.

我可以将 undefined 作为参数传递吗?

是的。

于 2010-02-10T10:53:53.780 回答
23

你不能(不应该?)将任何东西定义为未定义,因为变量将不再是未定义的——你只是将它定义为某个东西。

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

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

要正确测试undefinedor null,请使用这些:

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

if(testvar === null) { ... }
于 2010-02-10T09:24:45.707 回答
18

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

如果 onlynull可用,您将无法确定是否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/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined

这种行为也不是 JavaScript 特有的,它完善了布尔结果可以是truefalse、未知 ( null)、无值 ( undefined) 或出现问题 ( error) 的广义概念。

http://en.wikipedia.org/wiki/Undefined_value

于 2014-10-05T03:37:03.790 回答
14

检查空值的最佳方法是

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

对于未定义的

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

您可以分配一个未定义的变量。

testVar = undefined;
//typeof(testVar) will be equal to undefined.
于 2010-02-10T09:24:01.797 回答
8

是的,你可以,因为未定义被定义为未定义。

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
于 2014-04-18T13:59:44.877 回答
6

为了回答您的第一个问题,not 运算符 ( !) 将强制将它提供的任何内容转换为布尔值。所以null, 0, false,NaN""(empty string) 都将显示为 false。

于 2010-02-10T09:23:00.263 回答
4

JavaScript,如何在命令行上将变量设置为未定义:

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 中将变量设置为未定义:

把它放在 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 = 'rm -rf /';那么每当您将变量设置为未定义时,您都会收到该值。

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

于 2014-01-08T18:51:11.047 回答
3

试试这个:

// found on UglifyJS
variable = void 0;
于 2017-09-22T09:34:40.253 回答
2

只是为了好玩,这是一种将“未分配”分配给变量的相当安全的方法。为此,需要有人将与随机生成的字符串完全相同的名称添加到 Object 的原型中。我确信可以改进随机字符串生成器,但我只是从这个问题中提取了一个:Generate random string/characters in 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()];
于 2014-09-01T16:43:22.840 回答
1

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

if (document.getElementById)

标识符被转换为布尔值,因此undefined被解释为false. 当然还有其他值(如 0 和 '')也被解释为false,但是标识符不应该合理地具有这样的值,或者您乐于将这样的值视为未定义。

Javascript 有一个delete运算符,可用于删除对象的成员。根据变量的范围(即是否为全局变量),您可以删除它以使其未定义。

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

于 2010-02-10T09:41:46.907 回答