Showing posts with label Not Not. Show all posts
Showing posts with label Not Not. Show all posts

Tuesday, January 19, 2016

JavaScript Logical NOT Operator

There are some interesting things to note about the logical NOT operator in JavaScript. What I've found is that if you aren't aware of these, you may find yourself coding up some defects without knowing it. Also, being aware of some important usages may improve your code by reducing complexity.


If you are coming from a strongly typed language or just getting started in JavaScript from ground zero, you may interested to know that the NOT operator (!) has different behaviors depending on the value type that the variable represents at runtime.


For example you may have a statement:
var x = !y;
while x will be assigned a boolean value when this statement is executed, y could be any type (string, number, object, NaN, undefined, null, function) and how each is negated depends on the type.


Plus the process of negation involves first converting the value of the variable to boolean, then negating the result.


When converting to boolean, the following types are always false - null, undefined, NaN.


These are always true - object, function.


But string and number depend on the value - 0 is false and an empty string "" or '' is always false, while any other number or string is true.


An array is an object so it is always true even if it is empty.


{} is also true.


How much fun is that!?


Coming from C#, it would be great to write:


if(!x){
return;
}


instead of


if(!string.IsNullOrEmpty(x)){
return;
}


But when you cam expect x to be of any type, it would get much more complex.


In js, if you are in a position where you cannot use a guard, but need some logic to check for a value you can do the following:


if(!!x){
//do something useful
}


The underlying definition according to ecma 262 v5.1 of the ! is defined as negation of ToBoolean(GelValue(x))


where ToBoolean is defined here http://www.ecma-international.org/ecma-262/5.1/#sec-9.2


and GetValue, which is more complex, is http://www.ecma-international.org/ecma-262/5.1/#sec-8.7.1


Even though the abstract ToBoolean does not cover off on function type or array type (both object types) I listed those above for more clarity.


Since there is no ToBoolean in the JavaScript language, and there is a Boolean function (not to be confused with the constructor [new Boolean]), you'd be better of writing Boolean(x) instead of !!x for sake of clarity AND efficiency. Why have the runtime perform GetValue and ToBoolean twice?


The ecma standard defines the Boolean(x) function as simply calling the abstract ToBoolean(value)
http://www.ecma-international.org/ecma-262/5.1/#sec-15.6.1