最好检查未定义属性或设置为空

Better to check undefined property or set as null?

本文关键字:设置 属性 检查 未定义      更新时间:2023-09-26

用代码比用文字更容易解释,所以考虑以下场景:

// one
var myClass = function(a, b)
{
    if(a) this.a = a;
    if(b) this.b = b;
}
// two
var myClass = function(a, b)
{
    this.a = a || null;
    this.b = b || null;
}

假设你有一个方法被不断调用(多次/秒)

myClass.prototype.doSomething = function()
{
    if(this.a) // do something
    if(this.b) // so something else
};

在第一种情况下,你检查一个未定义的属性,而在第二种情况下,你检查一个已存在的属性,但与值null

哪种情况在JavaScript中表现更好?

我不确定我是否以最佳方式设置了测试,但是这个站点非常适合进行基准测试:

http://jsperf.com/or-pipe-versus-if

我得到的结果显示使用IF语句而不是OR操作符来设置默认值的性能要好6%

这两种情况都在测试构造函数中的a和b形参是否具有"真"值。这意味着在这两种情况下,如果传入0或空字符串,或者(显然)false,那么该值将被丢弃。不同之处在于第一种情况不会在对象上创建属性,而第二种情况默认为null。

无论如何,当你在doSomething()中实际使用它时,你仍然需要测试属性,而你的if (this.a)测试将工作,无论属性是否尚未设置,已设置为null,或已显式设置为未定义。

如果您不想在没有提供值时返回错误,我倾向于直接设置它们:

var myClass = function(a, b)
{
    this.a = a;
    this.b = b;
}

如果参数中没有提供该值,则将创建该属性,但将其设置为未定义,这将在doSomething()中的测试中以完全相同的方式工作,但是您将保存If或||测试,并具有不丢弃0,空字符串或false值的附加优势。这样构造函数就更简洁了…

就实际性能比较而言,您确实需要设置一个适当的测试(例如,在jsperf.com)。如果我不得不猜测,我会说if(a) this.a=a;版本平均会更快,因为它只在a为真时才执行赋值,但猜测性能是一个糟糕的计划。除非你在不同的浏览器中测试,否则你不会真正知道-可能是一种方式在IE中更快,而另一种方式在Chrome中更快。如果您设置了一个测试,请确保与类似于我上面展示的直接赋值进行比较。

编辑:我刚刚看到另一个答案,发现6%的性能差异。对于如此微小的差异,并注意到正如我上面提到的性能差异可能在某些浏览器中被逆转,我认为您最好编写对您的处理需求最有意义的代码,而不要担心性能。无论哪一种方法(或者三种方法都可以,如果你把我的答案包括在内的话)都是清晰、简单且运行良好的,它们只是做的事情不太一样。