Question

Today this question came up for the project I'm working on. The 'problem' is that I have some uncertainties in the data that is provided to me and on top of which I am building my application. This means it could be that some values sometimes are present but sometimes not. Because I want some consistency in my upper layers I wrote some 'sanitize' method that creates the consistency I want.

But...what is better?:

var myNewData = {};
myNewData['somevalue'] = (myOldData.somevalue) ? myOldData.somevalue : '';

or

var myNewData = {};
myNewData['somevalue'] = myOldData.somevalue || '';

And...why is it better? Is it performance? Readability? Just curious.

EDIT: To be clear. The 'somevalue' property does not necessarily had to be in the old data. Sometimes it is sometimes it is not.

EDIT2: Of course, if I know that the value of my old data contains a non-character value (numeric, boolean, etc.) I will default to it's appropriate value (0, true, etc.).

Était-ce utile?

La solution

I ran a performance test for this instructions:

myNewData['somevalue'] = (myOldData.somevalue) ? myOldData.somevalue : ''
myNewData['somevalue'] = (myOldData.somevalue) || ''

And as bonus the old if:

if (myOldData.somevalue)
    myNewData['somevalue'] = myOldData.somevalue
else
    myNewData['somevalue'] = '';

Both for myOldData.somevalue empty or not. For a test like this:

for (i = 0; i < 10; ++i) {
    for (j = 0; j < 100000000; ++j) {
        result = empty || "";
    }
}

Outer loop is to calculate an average (timing code is omitted). These are my results (lower index better performance):

Code  |   Empty               |     Not Empty
      |   IE9        CHROME   |     IE9        CHROME
------------------------------------------------------
?:    |   1435.1     551.1    |     1636.1     706.1
||    |   1450.3     488      |     1623.7     706.4
if    |   1436.2     491      |     1642.6     653.6
------------------------------------------------------

So I guess performances aren't the point here (anyway a better test should check what if the variable to test is something more complex).

Readability is something very opinion based. Personally I prefer || because it's clear enough and shorter but if you pick a C programmer maybe he won't like it while a C# programmer will understand it's like his ?? operator...

Autres conseils

You should aim at readability, and for this case || clearly wins.

The performance in Javascript is very hard to predict because it can vary wildly between different implementations and sometimes the result are apparently totally illogic (something that formally requires three lookups can be faster than something requiring one because may be the runtime engine has been specialized for that code path).

The problem with:

myNewData['somevalue'] = myOldData.somevalue || '';

is that, if myOldData.somevalue holds an acceptable falsy value, you'd still get the empty string.

So, with the first one you could at least make a strict check to have better control:

(myOldData.somevalue !== false) ? myOldData.somevalue : '';

Both will yield '' if myOldData.someValue is falsey (null, undefined, 0, '', etc), but the first one is very susceptible to copy/paste errors. Use the second form wherever possible and when coalescing all falsey answers to your default value is tolerable.

Note that if the base object -- myOldData -- could be null or undefined, it's a completely different ball game, and you'll need to do something like this:

myNewData.somevalue = ( myOldData && myOldData.someValue ) || '';

This assumes that myOldData is an object. If it's a string or number, bad things could happen here. (And gratuitous parentheses are always a good idea.)

I think both are equally good.

However, take care that they work only for maps containing string values. If the old map contains the value false, null or 0, they would be transformed into an empty string.

Therefore, I tend to prefer the generic case:

myNewData['somevalue'] = (myOldData.somevalue != undefined) ? myOldData.somevalue : '';

However, if you are handling strings only, the short myOldData.somevalue || '' looks concise and straightforward to me.

No difference.

Perfomance? Negligible.

Readability? You could say by yourself, what is easily to read to you and your colleagues. I'd prefer shorter one.

The second one is better in that you don't need to repeat the same thing and less chances you'll get an error. At the same time it is uncommon for people, used static-typed languages before.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top