检查未定义的属性还是将其设置为null更好?

3

用代码来解释比用文字更容易,因此考虑以下情景:

// 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中哪种情况执行更好?


如果你真的想知道性能数据,那么你应该自己制作一个jsperf(大约需要3分钟),并在你认为重要的浏览器中运行它。回答性能问题的唯一方法是在你认为相关的浏览器中进行测试。 - jfriend00
请记住,如果构造函数中的 a 或 b 参数是一个假值,如(0、""、false 等),那么这两种方法(一和二)都不起作用。为了允许这些值,请在参数中显式测试 a 和 b 是否为undefined - jfriend00
2个回答

3
我不确定我是否以最佳方式设置了测试,但是这个网站很适合做基准测试:http://jsperf.com/or-pipe-versus-if。我的测试结果表明,使用IF语句而不是OR运算符来设置默认值可以提高6%的性能表现。

我尝试了在Chrome/WinXP下进行相同的测试,“OR w/o values”是最快的情况,而其他所有情况都要慢92%或93% - 也就是说,其他所有情况都差不多。一个真实的案例可能只有一部分时间是false或not-provided值,我认为OP也想考虑到后来使用这些属性的速度(它们可能已经设置或未设置在测试时)。还是要给测试的设置和提供网站链接加1。 - nnnnnn

0

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

无论如何,在实际使用doSomething()时仍然必须测试属性,您的if(this.a)测试将适用于未设置属性,已设置为null或已明确设置为undefined的属性。

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

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%的性能差异。对于如此微小的差异,并且注意到如上所述性能差异在某些浏览器中可能会反转,我认为你最好编写符合处理要求的代码,不必担心性能。无论哪种方式(或者如果包括我的回答,则是三种方式)都很清晰简单且表现良好,只是它们并不完全做同样的事情...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接