Looking through the code of svelte.js I found this odd looking function:
function not_equal(a, b) {
return a != a ? b == b : a !== b;
}
Can someone explain to me in what situation comparing a variable with it self for inequality would resolve to false?
I know that != and == are weaker comparison operators than !== and === because they don't really care about the type but I still can't figure out what makes the not_equal function different from a simple a !== b
There are a couple of ways:
1. If a is NaN: NaN is not equal to anything, including itself.
let a = NaN;
console.log(a != a); // true
I think this is the likely reason for that conditional operator in not_equal, since with that function not_equal(NaN, NaN) is false (e.g., it considers NaN equal to itself). It's not clear to me why they went with the == rather than === in b == b, though.
2. (This doesn't apply to your function, just the a != a question.) If a is a property with a getter function that returns a different value when called twice in succession (because it returns a random value, or a value that changes over time, or the getter mutates the value, etc.) being used within a with statement (very unlikely), or similar using a Proxy rather than a with.
const obj = {
get a() {
return Math.random();
}
};
with (obj) {
console.log(a != a); // PROBABLY true
}
(Note: There are very good reasons not to use with, and it can't be used in strict mode.)
Other than that, I can't think of a way a != a would be true.
Related
First off, I am not a pro developer (yet), and hope someone could perhaps give me some input on a subject that seams easy, but it's not so easy.
How can I evaluate the value of multiple variables in a single IF statement?
This is something that still makes me scratch my head. I have seen others use it, but it is as if I am missing out on something. I have read an article about it, and looked at a logical operator app. Still frying my brain though.
Example: (Pseudo Code) if A is not B and A is not C, do something.
if(A !== B && A !== C) {
// Do Something
}
or
if(A !== B || A !== C) {
// Do Something
}
Which do I use? or is the answer perhaps NONE?
The code within the brackets will execute if the condition evaluates to true (or any loosely typed truthy value).
Consider A = 1; B = 2; C = 1;
(A !== B && A !== C) will evaluate to (true && false), which will evaluate to (false) (both conditions are not met).
(A !== B || A !== C) will (short circuiting aside) evaluate to (true || false), which will in turn evaluate to (true) (one of the conditions is met).
In the book 'Functional javascript' by Michael Fogus, I faced with one expression that I still can't undrestand.
Here is the function:
function defaults(d){
return function(o, k){
var val = fnull(_.identity, d[k]);
return o && val(o[k]);
}
}
where
function fnull(fun /*, defaults*/){
var defaults = _.rest(arguments);
return function(/* args */){
var args = _.map(arguments, function(e, i){
return existy(e)?e : defaults[i];
});
return fun.apply(null, args);
};
};
function existy(x){return x != null}
(underscore is the object of Underscore.js library)
and the example of use:
function doSomething(config){
var lookup = defaults({critical:108});
return lookup(config, 'critical');
}
doSomething({critical: 9});
//=> 9
doSomething({});
//=> 108
I've recreated exapmle in node.js and it works fine, but I wonder why is the logical 'and' in the return line of 'default' function?
return o && val(o[k]);
What is the point of doing that? I checked the exapmle with
return val(o[k]);
and it also worked well.
It's hard to believe that this is just a mistake...
The logical and will make sure the second part is only evaluated if the first part is true. If o does not evaluate to true, the expression returns false. Otherwise, it returns val(o[k]).
This is used as a quick check to see if o is not false / null / undefined.
return o && val(o[k])
mean that if "o" is TRUE it will return "val(o[k])"
given "expr1 && expr2":
Returns expr1 if it can be converted to false; otherwise, returns expr2. Thus, when used with Boolean values, && returns true if both operands are true; otherwise, returns false.
That is smart usage of something called short "short-circuiting" in logical expressions.
As logical expressions are evaluated left to right, they are tested
for possible "short-circuit" evaluation using the following rules:
false && (anything) is short-circuit evaluated to false.
true ||(anything) is short-circuit evaluated to true.
The rules of logic guarantee that these evaluations are always correct. Note that the (anything) part of the above expressions is not evaluated (meaning not ran at all), so any side effects of doing so do not take effect. There are also benefits to it.
Usage:
Make your expressions evaluate faster by putting something easily calculable or likely to be true/fail at leftmost position in expression.
For example parOfExpressionLikelyToBeTrue && (rest of expression) will in most cases not even calculate the other part of expression. Same goes for parOfExpressionLikelyToBeTrue || (rest of espression).
Same can be used if something is very time consuming to calculate, you push it as far back to the right in expression. For example (rest of the expression) && ThisCostsALotOfTime or (rest of the expression) || ThisCostsALotOfTime. Here when first parts of expression short-circuit you save time on your time consuming part.
Short circuit existence evaluation. Lets say you need to check if your object's property pr is 3? What would you do? obj.pr === 3? Yes and no. What if property is missing? It's fine you will get undefined and that is not === 3. But what if object is not there. You will get trying to read pr of undefined error. You can use short-circuit logic here to you benefit by being defensive and writing the expression as if (obj || obj.pr === 3). This ensures there are no errors, only true and false.
Short circuit initialization. Let's say you wanna say variable a is b. But b might be undefined. And you wanna your variable to have a default. You could write a=b and then check if a is undefined and set it to default or you can be clever and write it as a = b || 3. This way a is b or if be is undefined it's 3. Ofc, you can use this for late initialization as well a = a || 3.
Making sure object for function exists before trying to run function. Same as before mentioned with properties you might wanna test if object containing the function exists before running the function. Let's say you got object obj and function fn as it's property. You might call that function like obj.fn(). It's fine, but if obj is undefined you will get an error. Being defensive you might wanna write: obj && obj.fn().
Running the function only if there is one. Since functions in JS can be passed to other functions you can not be sure at run time it's there. Being defensive you might wanna run your function as (typeof passedFunction === "function" && passedFunction() instead just passedFunction() which my produce an error.
other smart things like guardian expressions etc which are complicated and too many to for me to remember all and you should avoid them anyway for better code readability.
In javascript, which will be better way to check conditional statement in terms of performance, robustness and which is the best practice?
var x = null;
// this condition is checked frequently and x will be set to null or some value accordingly
if(x !== null){...}
OR
if(!!x){...}
You could just do
if (x) { ... }
Simply says, if x is a truthy value.
As Nina pointed out. I would always add some extra validation, depending on what I'm expecting.
if (x && x > 0) { ... }
Or
if (x && x instanceof Array)
But I'm always checking x has some sort of value and isn't undefined or null
It's never necessary to write if(!!x){...}. That is exactly the same thing as writing if(x){...}. Using the ! operator twice converts a value to a boolean that reflects whether it is "truthy" or not. But the if statement does that anyway: it tests whether the value you provide is "truthy". So whether you use !! or not it will do the same thing.
if(x !== null){...} is something else entirely. It doesn't just check whether x is "truthy", it specifically compares the value of x with null. For example, if x has the numeric value 0, if(x){...} or if(!!x){...} will not execute the ... code, because 0 is a "falsy" value, but if(x!==null) will execute the ... code, because 0 is not the same value as null.
A related example is if(x!=null){...} or if(x==null){...}. (Note the use of != or == instead of !== or ===.) This is a bit of a special case in JavaScript. When you compare against null using the != or == operator, it actually compares against either null or undefined and treats those two values the same. In other words, if x is either null or undefined, then if(x==null){...} will execute the ... code, but if(x!=null){...} will not execute the ... code.
It's generally recommended to avoid the == and != operators and use the strict comparison === or !== instead, but treating null and undefined the same can be useful in some situations, so this is a case where the non-strict operators are helpful.
In any case, the real question to ask is what is the purpose of your code, and what specifically do you need to test for here?
Assuming you need to check for a value which is strict inequality !== to null
this condition is checked frequently and x will be set to null or some value accordingly
if (x !== null) { /* */ }
Then you can only use the above comparison. Any other comparison would return a wrong result.
For example
var x = 0;
if (x !== null) { // true
console.log(x + ' !== null');
}
if (x) { // false
console.log(x);
}
// some more checks
console.log(undefined !== null); // true
console.log(undefined != null); // false
Edit: My response was quite wrong which I learned after my conversation with Nina Scholz in her own response to this thread. I updated accordingly.
There are many ways to check values depending on the type you expect to use. Therefore the problem is not so much about performance as it is with correct evaluation. Starting with your examples:
if(x != null)
This will evaluate to false if the value of x is either null or `undefined'.
The next case:
if(!!x)
This is an entirely different operation. It casts the value of x as a boolean, and in most cases if(x) will work the same way. But now, if the value is falsy, like 0, the empty string, the expression returns false. So, if expecting a number, you should check for the zero value:
if(x || (0 === x))
Bear in mind that if x were anything other than an int, the expression returns true.
And the case where you expect a string:
if(x || ('' === x))
Same thing here, if x was, say 12, the expression returns true.
I could go on with lots of examples. Unfortunately there are certain expressions that work in unexpected ways. For instance, it should be easy to check if a value is a number by calling isNaN(number), but if the value is an empty string or a representation of an array index ('2'), isNaN returns false.
I recommend you to check this table with all the type conversions so that you become more aware on how to check the validity of a value.
Given this function:
var test = function(param1, param2_maybe_not_set) {
var my_object = {};
// code here...
}
What's the best, in your opinion?
my_object.new_key = (param2_maybe_not_set === undefined) ? null : param2_maybe_not_set;
OR
my_object.new_key = (param2_maybe_not_set === void 0) ? null : param2_maybe_not_set;
OR
my_object.new_key = (typeof param2_maybe_not_set === 'undefined') ? null : param2_maybe_not_set;
Alternatively, would this shortened expression be correct?
my_object.new_key = param2_maybe_not_set || null;
All four methods work (in the NodeJS console at least). Also jsPerf doesn't show a big gap between any of these (http://jsperf.com/typeof-performance/8)
Which one should be used, as a good practice?
They are not strictly equivalent, but can often be used interchangeably. Here are the major differences between them:
x === undefined: this performs a strict-equality comparison between the value and undefined, meaning that only a actual value of undefined will be true, whereas similar values like null or 0 will be false.
In the case of a function call, this check does not differentiate between f(a) and f(a, undefined) (in fact, none of the examples will; to differentiate, you'll have to look at arguments).
x === void 0: this uses the void keyword, which evaluates any expression and returns undefined. This was mostly done in the olden days to prevent surprises from people redefining the global undefined variable, but is not so useful nowadays (ECMAScript 5 mandates that undefined be read-only)
typeof x === 'undefined': this uses the typeof keyword, which has a unique ability - namely, that the operand is unevaluated. This means that something like typeof foobarbaz returns 'undefined' even if no such variable foobarbaz exists at all. Contrast this with foobarbaz === undefined, which will throw a ReferenceError if the variable name has never been declared.
x || null: this is the simplest and probably most readable alternative. The || operator is often used to "set defaults" on arguments, and can be chained like x || y || z || null.
In most cases, this is the idiomatic technique used. However, note that || performs implicit conversions, which means that any "falsy" values will trigger the next value (meaning that it can't differentiate between undefined, false, null, 0, '', and NaN). So, if your function expects to receive falsy values as arguments, it may be more prudent to explicitly check for undefined.
The option chosen to be an idiom in Javascript development to force a value for an unspecified argument is actually the last:
my_object.new_key = param2_maybe_not_set || null;
So this one should be preferrable since a lot of Javascript developers will immediately get its purpose.
Best.
Throughout many third-party libraries and best practices blogs/recommendations, etc... it is common to see syntax like this:
typeof x === 'object' (instead of typeof x == 'object')
typeof y === 'string' (instead of typeof x == 'string')
typeof z === 'function' (instead of typeof x == 'function')
If the typeof operator already returns a string, what's the need to type check the return value as well? If typeof(typeof(x)) is always string, no matter what x actually is, then == should be sufficient and === unnecessary.
Under what circumstances will typeof not return a string literal? And even if there's some fringe case why is the additional type check being used for object, string, function, etc...
To answer the main question - there is no danger in using typeof with ==. Below is the reason why you may want to use === anyway.
The recommendation from Crockford is that it's safer to use === in many circumstances, and that if you're going to use it in some circumstances it's better to be consistent and use it for everything.
The thinking is that you can either think about whether to use == or === every time you check for equality, or you can just get into the habit of always writing ===.
There's hardly ever a reason for using == over === - if you're comparing to true or false and you want coercion (for example you want 0 or '' to evaluate to false) then just use if(! empty_str) rather than if(empty_str == false).
To those who don't understand the problems of == outside of the context of typeof, see this, from The Good Parts:
'' == '0' // false
0 == '' // true
0 == '0' // true
false == 'false' // false
false == '0' // true
false == undefined // false
false == null // false
null == undefined // true
' \t\r\n ' == 0 // true
If the typeof operator already returns
a string, what's the need to type
check the return value as well? If
typeof(typeof(x)) is always string, no
matter what x actually is, then ==
should be sufficient and ===
unnecessary.
It's subjective. You can just as easily turn this around, and ask, "Why would you use == when you don't expect implicit conversions?" Both work fine here, so use the one you feel expresses your intention better. Try to be consistent within a project.
There's no reason at all to favour === over == in this case, since both operands are guaranteed to be strings and both operators will therefore give the same result. Since == is one character fewer I would favour that.
Crockford's advice on this is to use === all the time, which is reasonable advice for a beginner but pointlessly paranoid if you know the issues (covered in other answers).
Because === is quicker than ==, due to omitting type coercion.
Sure it is probably a negligible difference but it is still there.
Triple equal operators are mostly used for variable type and value checking (all in 1 expression), also known as equality without type coercion.
Example:
var a = 1;
var b = 1;
var c = "1";
var d = "1";
alert (a === b); //True, same value and same type (numeric)
alert(c === d); //True, same value and same type (string)
alert(b === c); //False, different type but same value of 1
See Doug Crockford's YUI Theater on type coercion.
If the typeof operator already returns
a string, what's the need to type
check the return value as well? If
typeof(typeof(x)) is always string, no
matter what x actually is, then ==
should be sufficient and ===
unnecessary.
The most efficient reason for not using typeof and rather the === operator would be for type coercion (interpretation) between browsers. Some browsers can pass 6=="6" as true and some wouldn't (depending on the strictness of the JS interpreter) so by introducing type coercion would clarify this.
Also, it would bring the "Object-Orientativity" approach to it since JavasScript's variables are not type-based variables (i.e. variable types are not declared on compile time like in Java).
E.g. in Java, this would fail:
if ("6" instanceof Number) { // false
Hope I answered your question.