Code efficiency and speed comparison in javascript -assignment vs conditional checking - javascript

I have a timer object written in javascript and my goal is to make it as efficient and fast and thus as accurate as possible.
One of my concerns has to do with a specific case that could generally be applied to all manners of coding and I'm sure has been asked before, I just am not sure what terms to use when searching for it.
My question is which of these 2 cases is faster/more efficient?
Case 1: Assigning a variable some value in a repeated section of code, even when you know the value only needs to be assigned once.
Case 2: Checking the value of the variable, thus conditionally assigning it.
function runOnce(){
timer.someValue = { //some object...};
}
function someRepeatedFunction(){
timer.someValue = null;
//vs
if(timer.someValue){
timer.someValue = null;
}
}
Which of those cases would be faster?

Micro-optimization #1
If you insist on the conditional checking, I would bypass using the == operator (that I think Javascript uses automatically) and go for the === operator.
The identity === operator behaves identically to the equality == operator except no type conversion is done, and the types must be the same to be considered equal.The == operator will compare for equality after doing any necessary type conversions. The === operator will not do the conversion, so if two values are not the same type === will simply return false. It's this case where === will be faster, and may return a different result than ==. In all other cases performance will be the same.
Micro-optimization #2
With respect to the choice between the assignment & conditional checking, it seems logical to go for assignment in the case of using a global variable (like the one you seem to be using). Unless you plan on handling cases in an else situation there's no need to continually check what the current typeof the object or it's value is.

Related

OK to use type coercion when checking for undefined/null?

Is it acceptable to use type coercion (== instead of ===) to check for undefined/null?
What are the downsides? Is there a better way to check for undefined/null?
Clarification: I am looking for a statement that will check for both undefined and null.
test(null);
test(undefined);
function test(myVar) {
if (myVar != undefined) {
alert('never gets called')
}
}
I'm going to attempt to address this question as objectively as possible, but it deals with some mushy "best practices" opinion stuff that can trigger people to forget that there's more than one way to do things.
Is it acceptable to use type coercion (== instead of ===) to check for undefined/null?
It's acceptable to write code however you see fit regardless of anyone who tells you otherwise. Including me.
That's not really helpful here, so let me expand on that a bit, and I'll let you decide how you feel about it.
Code is a tool that can be used to solve problems, and == is a tool within JavaScript code to solve a specific problem. It has a well-defined algorithm which it follows for checking a type of equality between two parameters.
===, on the other hand, is a different tool that solves a different, specific problem. It also has a well-defined algorithm which it follows for checking a type of equality between two parameters.
If one tool or the other is appropriate for your use-case, then you shouldn't hesitate to use the tool.
If you need a hammer, use a hammer.
But if all you have is a hammer, then everything looks like a nail, and this is the core issue with ==. Developers coming from other languages often aren't aware of how == works and use it when === would be appropriate.
In fact, most use cases are such that === should be preferred over ==, but as you've asked in your question: that's not true in this instance.
What are the downsides?
If you relax your standards for === and allow developers to use == you may very well get bitten by misuse of ==, which is why sticking religiously to === may be acceptable to some, and seem foolish to others.
if (val === null || val === undefined) {...
is not particularly difficult to write, and is very explicit about intent.
Alternatively,
if (val == null) {...
is much more concise, and not difficult to understand either.
Is there a better way to check for undefined/null?
"better" is subjective, but I'm going to say, "no" anyway because I'm not aware of any that improve the situation in any meaningful way.
At this point I will also note that there are other checks that could be performed instead of null/undefined. Truthy/falsey checks are common, but they are another tool used to solve yet another specific problem:
if (!val) {...
is much more concise than either of the previous options, however it comes with the baggage of swallowing other falsey values.
Additional notes on enforcement via linting:
If you follow the strictness of Crockford's JSLint, == is never tolerated, in the understanding that a tool that's "sometimes useful" but "mostly dangerous" isn't worth the risk.
ESLint, on the other hand, allows for a more liberal interpretation of the rule by providing an option to allow null as a specific exception.
== undefined and == null are both equivalent to checking if the value is either undefined or null, and nothing else.
As for "acceptable", it depends on who is looking at the code, and whether your linter is configured to ignore this special case.
I can tell you for sure that some minifiers already do this optimisation for you.
The ideal way to test for undefined is using typeof. Note you only need to test them separately if you care about a difference between undefined and null:
test(null);
test(undefined);
function test(myVar) {
if (typeof myVar === "undefined") {
// its undefined
}
if (myVar === null) {
// its null
}
}
If you don't care if its undefined/null, then just do:
test(null);
test(undefined);
function test(myVar) {
if (!myVar) {
// its undefined or null, dunno which, don't care!
}
}

What does undefined === undefined compare?

After reading through Lodash's code a bit and learning that it uses typeof comparisons more often than not (in its suite of _.is* tools), I ran some tests to confirm that it is faster, which it is, in fact (if marginally).
Discussing my confusion with a fellow developer, he pointed out that in case 1:
var a;
return a === undefined;
Two objects undergo comparison, whereas in case 2 (the faster case):
var a;
return typeof a === 'undefined';
is a far more simple and flat string compare.
I was always of the thought that undefined inhabited a static place in memory, and all triple equals was doing was comparing that reference. Who's correct (if either)?
JSPerf Test:
http://jsperf.com/testing-for-undefined-lodash
In this case (with var a in scope), both of the two posted pieces of code have identical semantics as x === undefined is only true when x is undefined and typeof x will only returned "undefined" when x is undefined (or not resolved in the execution context).
That out of the way, we end up with:
undefined === undefined
vs.
"undefined" === "undefined"
So, even in a naive implementation case the "difference" between the two is SameObject(a,b) vs StringEquals(a,b) as per the rules for Strict Equality Comparison.
But modern implementations of JavaScript are quite competitive and, as can be seen, are very well optimized for this case. I don't know of the exact implementation details, but there are at least two different techniques that could allow the performance (in FF/Chrome/Webkit) to be the same for both cases:
ECMAScript implementations may intern strings, such that there is only one "undefined" string. This would make the StringEquals(a,b) effectively the same as SameObject(a,b) which would end up amounting to a "pointer comparison" in the implementation - this alone could explain why the performance is the same.
Additionally, because typeof x === "undefined" is a common idiom, it could be translated during the parsing to end up in a special call that performs the same, say TypeOfUndefined(x). That is, the implementation could bypass the === (and StringEquals) entirely if it so chose.
IE comes out as a the "clear loser" and seems to be missing an applicable optimization here.
The implementation of the undefined value is outside the scope of ECMAScript; there are no mandates that it must be a single value/object in the implementation.
In practice, however, undefined (and other special values like null) is most likely implemented as either a singleton (e.g. "one object in memory") or as an immediate value or value flag (such that there is actually no undefined object).
According to EcmaScript (see http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf ) if both expressions are strings (typeof returns a string) it perfroms a string comparison (char by char), otherwise it just compares references (in case when one of the sides is undefined). There is no way that string comparison would be more efficient then simple two numbers (i.e. addresses in memory) comparison. However it is possible that it is highly optimized (browsers do not follow EcmaScript in 100%) so it's really hard to say.
Proper benchmark:
http://jsperf.com/undefined-comparison-reference-vs-string
Note that in your test the initial value of a is undefined (may or may not matter, it seems that it does).
Conclusion: always use
return a === undefined;
It definitely won't be slower and it might be faster. Besides it seems more natural to compare something to a special undefined object rather then to a string.

Is there a way to conditionally call a function with one line of JavaScript?

I would like an elegant way to only execute a function if some condition is met. Two options that I know of are if conditions and the tertiary operator.
if
if(headerExists($listview) === false)
addHeader($listview, template);
tertiary
headerExists($listview) ? null : addHeader($listview);
To me, the if makes the logic a little harder to understand when you look at the function as a whole. The tertiary function seems smart but you never see it anywhere and having to declare null is explicitly wasted space.
The third option is to (ab)use the short-circuit behaviour of the logical operators:
!headerExists($listview) && addHeader($listview, template);
// or
headerExists($listview) || addHeader($listview, template);
However, this is only a minification technique (which doesn't even make the code a lot shorter). Use an if-statement for readability reasons, if you want without a block and in one line:
if (!headerExists($listview)) addHeader($listview, template);

Primitives and Object Wrapper Equivalence in JavaScript

EDIT: Based on everyone's feedback, the original version of this question is more design-related, not standards-related. Making more SO-friendly.
Original:
Should a JS primitive be considered "equivalent" to an object-wrapped version of that primitive according to the ECMA standards?
Revised Question
Is there a universal agreement on how to compare primitive-wrapped objects in current JavaScript?
var n = new Number(1),
p = 1;
n === p; // false
typeof n; // "object"
typeof p; // "number"
+n === p; // true, but you need coercion.
EDIT:
As #Pointy commented, ECMA spec (262, S15.1.2.4) describes a Number.isNaN() method that behaves as follows:
Number.isNaN(NaN); // true
Number.isNaN(new Number(NaN)); // false
Number.isNaN(+(new Number(NaN))); // true, but you need coercion.
Apparently, the justification for this behavior is that isNaN will return true IF the argument coerces to NaN. new Number(NaN) does not directly coerce based on how the native isNaN operates.
It seems that the performance hit and trickiness in type conversion, etc, of directly using native Object Wrappers as opposed to primitives outweighs the semantic benefits for now.
See this JSPerf.
The short answer to your question is no, there is no consensus on how to compare values in JS because the question is too situational; it depends heavily on your particular circumstances.
But, to give some advice/provide a longer answer .... object versions of primitives are evil (in the "they will cause you lots of bugs sense", not in a moral sense), and should be avoided if possible. Therefore, unless you have a compelling reason to handle both, I'd suggest that you do not account for object-wrapped primitives, and simply stick to un-wrapped primitives in your code.
Plus, if you don't account for wrapped primitives it should eliminate any need for you to even have an equals method in the first place.
* Edit *
Just saw your latest comment, and if you need to compare arrays then the built-in == and === won't cut it. Even so, I'd recommend making an arrayEquals method rather than just an equals method, as you'll avoid lots of drama by keeping your function as focused as possible and using the built-in JS comparators as much as possible.
And if you do wrap that in some sort of general function, for convenience:
function equals(left, right) {
if (left.slice && right.slice) { // lame array check
return arrayEquals(left, right);
}
return left == right;
}
I'd still recommend against handling primitive-wrapped objects, unless by "handle" you make your function throw an error if it's passed a primitive-wrapped object. Again, because these objects will only cause you trouble, you should strive to avoid them as much as possible, and not leave yourself openings to introduce bad code.

Comparison operation - Correct Syntax?

Coming from PHP I understand the difference in using == verses === in a comparison operation, but with JavaScript is it acceptable to use == or ===?
I wanted to validate my JavaScript code and found JSLint. While running the validation with JSLint I see these types of messages.
Some examples:
var show = $('input[name=female]:checked').val() == "true";
Problem at line 278 character 70: Expected '!==' and instead saw '!='.
and
var show = $('input[name=living]:checked').val() != "false";
Problem at line 283 character 38: Expected '!==' and instead saw '!='.
So My question is, Would using the current syntax of == or != be valid/correct or do I need to use === and !== ?
EDIT: Just to point out the code does work
It is correct in a way but JSLint expects strict comparison to prevent problems with type conversion.
It is good practice to always use strict comparison and "normal" comparison only where you really need/want it (because you want to make use of type conversion for some reason).
From JSLint's documentation:
== and !=
The == and != operators do type
coercion before comparing. This is bad
because it causes ' \t\r\n' == 0 to
be true. This can mask type errors.
If you only care that a value is
truthy or falsy, then use the short
form. Instead of
(foo != 0)
just say
(foo)
and instead of
(foo == 0)
say
(!foo)
Always use the === and !==
operators.
Crockford and JSLint are somewhat dogmatic on this point, and I think over-prescriptive. Always using === rather than == is a reasonable rule of thumb for inexperienced JavaScript developers, but if you know the basic rules then there is no problem with using ==. In particular, if the two operands are guaranteed to be of the same type (such as in a typeof comparison like typeof foo == "undefined") then the two operators are specified to follow precisely the same steps.
There is also a reasonable point about habitually using === removing the need to think about which operator to use, but frankly I prefer to be forced to consider all the possible values of the two operands I'm comparing and find JSLint unnecessarily nannying.
The == syntax is valid but in some cases it can lead to rather nasty bugs in large projects. If you don't have a good reason to use == you should by default write JavaScript with === because it checks for type as you know.
It works either way, but you will save yourself pain in the future if you default to ===.
Depends on the situation.
=== is often preferred because you won't have any false-positives that you might not have considered (it might also be slightly quicker in some implementations because it compares to less potential values, although I haven't checked that, just a thought, and the speed difference would be negligible).
== is often more convenient to cover many/all cases (if I'm not mistaken, jQuery doesn't pass JSLint because in some places the code intentionally uses == to cover a multitude of cases rather than testing each one individually).
you can do just == and !=, I don't think there would be any problems with that.

Categories

Resources