How can I break the law of non-contradiction in Javascript? - javascript

The law of non-contradiction dictates that two contradictory statements cannot both be true at the same time. That means that the expressions
(a && !a)
(a == !a)
(a === !a)
should always evaluate to a falsy value, and
(a || !a)
should always evaluate to a truthy value.
Fortunately, though, Javascript is a fun language that allows you to do all sorts of sick things. I bet someone a small fortune that it's possible to convince Javascript to break the law of non-contradiction, or, at least, convincingly make it look like it's breaking the law of non-contradiction. Now I'm trying to make all four of the above code examples give the unexpected result.
What would be a good way to go about this?

The best I can do is:
[] == ![] // true
or
var a = [];
a == !a
Of course this is really doing [] == false // true and !![] == ![] // false. It's really just a technicality.
EDIT: This is really a joke, but does work:
var a = false; var b = function() { return a = !a };
console.log(!!(b() && !b())); // true
console.log(b() == !b()); // true
console.log(b() === !b()); // true
console.log(b() || !b()); // true

This one will do the trick:
var a = '0';
a == !a
(evaluates to true)
In this case, a == false and !a == false.

a=NaN;
var a=NaN,
A=[(a && !a), (a == !a),(a === !a),(a || !a)];
alert(A)
/* returned value: (Array)
NaN,false,false,true
*/

I still haven't found anything to break && and ===, but here's one for == and ||:
Object.prototype.toString = function() {
return false;
};
a = {};
b = (a || !a);
alert(a || !a); //alerts false
alert(b == !b); //alerts true

Related

Multiple Values after Comparison Operator [duplicate]

I want to write an if/else statement that tests if the value of a text input does NOT equal either one of two different values. Like this (excuse my pseudo-English code):
var test = $("#test").val();
if (test does not equal A or B){
do stuff;
}
else {
do other stuff;
}
How do I write the condition for the if statement on line 2?
Think of ! (negation operator) as "not", || (boolean-or operator) as "or" and && (boolean-and operator) as "and". See Operators and Operator Precedence.
Thus:
if(!(a || b)) {
// means neither a nor b
}
However, using De Morgan's Law, it could be written as:
if(!a && !b) {
// is not a and is not b
}
a and b above can be any expression (such as test == 'B' or whatever it needs to be).
Once again, if test == 'A' and test == 'B', are the expressions, note the expansion of the 1st form:
// if(!(a || b))
if(!((test == 'A') || (test == 'B')))
// or more simply, removing the inner parenthesis as
// || and && have a lower precedence than comparison and negation operators
if(!(test == 'A' || test == 'B'))
// and using DeMorgan's, we can turn this into
// this is the same as substituting into if(!a && !b)
if(!(test == 'A') && !(test == 'B'))
// and this can be simplified as !(x == y) is the same as (x != y)
if(test != 'A' && test != 'B')
ECMA2016 answer, especially good when checking against multiple values:
if (!["A","B", ...].includes(test)) {}
In general it would be something like this:
if(test != "A" && test != "B")
You should probably read up on JavaScript logical operators.
I do that using jQuery
if ( 0 > $.inArray( test, [a,b] ) ) { ... }
For a larger number of values that is checked against often, it may be more efficient to check if the value does not exist in a Set.
const values = new Set(["a", "b"]);
if(!values.has(someValue)){
// do something
} else {
// do something else
}
var test = $("#test").val();
if (test != 'A' && test != 'B'){
do stuff;
}
else {
do other stuff;
}
You used the word "or" in your pseudo code, but based on your first sentence, I think you mean and. There was some confusion about this because that is not how people usually speak.
You want:
var test = $("#test").val();
if (test !== 'A' && test !== 'B'){
do stuff;
}
else {
do other stuff;
}
This can be done with a switch statement as well. The order of the conditional is reversed but this really doesn't make a difference (and it's slightly simpler anyways).
switch(test) {
case A:
case B:
do other stuff;
break;
default:
do stuff;
}

Write a Function 'or' without '||'

Write a function 'or' without ||
Given 2 boolean expressions, "or" returns true or false, corresponding to the || operator.
*Should use ! and &&
function or(expression1, expression2) {
return !expression1 && expression1 && !expression2 && expression1
}
I've tried that but at the same time I'm confused on what the question is exactly asking
Expected Output:
var output = or(true, false);
console.log(output); // --> true;
Some basic consideration, with De Morgan's laws:
!(a && b) = !a || !b
!(a || b) = !a && !b
function or(a, b) {
return !(!a && !b);
}
console.log(or(false, false)); // false
console.log(or(false, true)); // true
console.log(or(true, false)); // true
console.log(or(true, true)); // true
here is the working solution
function or(a, b){
if(!a && !b)
return false
return true;
}
console.log(or(true, true));
console.log(or(true, false));
console.log(or(false, true));
console.log(or(false, false));
hope this helps!!
The concept they are asking you to show is something called a NAND or Not AND
NAND is the most common type of of logic operator in electronics and can be used to represent all other logic.
You can find a representation of what you should be modeling here: https://en.wikipedia.org/wiki/NAND_logic#OR
Your implementation:
return !a && b && !a && b
For true and false this evaluates to:
return !true && true && !false && false;
i.e.
return false && true && true && false;
Because of lazy evaluation, it doesn't even evaluate anything after the first false && because false && x is false regardless of the value of x. For any input, one of the terms is false, so it will always return false.
It may help if you break it into smaller parts:
boolean bothFalse = !a && !b
boolean notBothFalse = !bothFalse;
return notBothFalse;
But using brackets () you can express this in a single line. I'll leave this as an exercise for you.

Lost in javascript comparisons

I'm writing a script to be executed when my body element hasn't got any of the following classes:
a OR b OR c AND d
I tried this, but it doesn't seem to do the trick:
if ((!$('body').hasClass('a')) || (!$('body').hasClass('b')) || ((!($('body').hasClass('c')) && (!$('body').hasClass('d'))))) {
}
UPDATE
This seems to work:
if (!($('body').hasClass('a') || $('body').hasClass('b') || $('body').hasClass('c') && $('body').hasClass('d'))) {
}
use
$(function(){
if ((!$('body').hasClass('a')) || (!$('body').hasClass('b')) || !($('body').hasClass('c') && $('body').hasClass('d'))) {
}
});
You are looking for a body that doesnt have any of the classes, so you need to use &&. Heres what happens:
if(hasclass(a) || hasclass(b)) = if(true OR false) = if(true)
Above the OR operator || means that once it hits a true evaluation, it will execute your if-block.
if(hasclass(a) && hasclass(b)) = if(true AND false) = if(false)
Here the AND operator && means that once you hit a false evaluation, you block won't be executed.
You want the last thing to happen, since you want it to have neither of the classes. Learn how to play with these operators as they can be very confusing. As long as you remember that the AND operator will execute only if all statements are true and the OR operator will only execute if one of the statements is true. Nested operators work the same, so if((a = b && b = c) || (a = c)) will execute if a,b and c are the same OR when a and c are the same, but not when a and b are the same or a and c are the same.
More on expression and operators (specifically Bitwise and a must read): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Bitwise_operators

Javascript Logical Operator:?

I was examining the src of underscore.js and discovered this:
_.isRegExp = function(obj) {
return !!(obj && obj.test && obj.exec && (obj.ignoreCase || obj.ignoreCase === false));
};
Why was "!!" used? Should it be read as NOT-NOT or is there some esoteric JS nuance going on here?
It is just an obtuse way to cast the result to a boolean.
Yes, it's NOT-NOT. It is commonly used idiom to convert a value to a boolean of equivalent truthiness.
JavaScript understands 0.0, '', null, undefined and false as falsy, and any other value (including, obviously, true) as truthy. This idiom converts all the former ones into boolean false, and all the latter ones into boolean true.
In this particular case,
a && b
will return b if both a and b are truthy;
!!(a && b)
will return true if both a and b are truthy.
The && operator returns either false or the last value in the expression:
("a" && "b") == "b"
The || operator returns the first value that evaluates to true
("a" || "b") == "a"
The ! operator returns a boolean
!"a" == false
So if you want to convert a variable to a boolean you can use !!
var myVar = "a"
!!myVar == true
myVar = undefined
!!myVar == false
etc.
It is just two ! operators next to each other. But a double-negation is pointless unless you are using !! like an operator to convert to Boolean type.
It will convert anything to true or false...

JavaScript equality transitivity is weird

I've been reading Douglas Crockford's JavaScript: The Good Parts, and I came across this weird example that doesn't make sense to me:
'' == '0' // false
0 == '' // true
0 == '0' // true
false == undefined // false
false == null // false
null == undefined // true
The author also goes on to mention "to never use == and !=. Instead, always use === and !==". However, he doesn't explain why the above behavior is exhibited? So my question is, why are the above results as they are? Isn't transitivity considered in JavaScript?
'' == '0' // false
The left hand side is an empty string, and the right hand side is a string with one character. They are false because it is making a comparison between two un identical strings (thanks Niall).
0 == '' // true
Hence, why this one is true, because 0 is falsy and the empty string is falsy.
0 == '0' // true
This one is a bit trickier. The spec states that if the operands are a string and a number, then coerce the string to number. '0' becomes 0. Thanks smfoote.
false == undefined // false
The value undefined is special in JavaScript and is not equal to anything else except null. However, it is falsy.
false == null // false
Again, null is special. It is only equal to undefined. It is also falsy.
null == undefined // true
null and undefined are similar, but not the same. null means nothing, whilst undefined is the value for a variable not set or not existing. It would kind of make sense that their values would be considered equal.
If you want to be really confused, check this...
'\n\r\t' == 0
A string consisting only of whitespace is considered equal to 0.
Douglas Crockford makes a lot of recommendations, but you don't have to take them as gospel. :)
T.J. Crowder makes an excellent suggestion of studying the ECMAScript Language Specification to know the whole story behind these equality tests.
Further Reading?
The spec.
yolpo (on falsy values)
The answer to this question has to do with how JavaScript handles coercion. In the case of ==, strings are coerced to be numbers. Therefore:
'' == '0' is equivalent to '' === '0' (both are strings, so no coercion is necessary).
0 == '' is equivalent to 0 === 0 because the string '' becomes the number 0 (math.abs('') === 0).
0 == '0' is equivalent to 0 === 0 for the same reason.
false == undefined is equivalent to 0 === undefined because JavaScript coerces booleans to be numbers when types don't match
false == null is equivalent to 0 === null for the same reason.
null == undefined is true because the spec says so.
Thanks for asking this question. My understanding of == is much better for having researched it.
You can actually write a JavaScript function that behaves exactly like == that should give you some insight into how it behaves.
To show you what I mean here is that function:
// loseEqual() behaves just like `==`
function loseEqual(x, y) {
// notice the function only uses "strict" operators
// like `===` and `!==` to do comparisons
if(typeof y === typeof x) return y === x;
if(typeof y === "function" || typeof x === "function") return false;
// treat null and undefined the same
var xIsNothing = (y === undefined) || (y === null);
var yIsNothing = (x === undefined) || (x === null);
if(xIsNothing || yIsNothing) return (xIsNothing && yIsNothing);
if(typeof x === "object") x = toPrimitive(x);
if(typeof y === "object") y = toPrimitive(y);
if(typeof y === typeof x) return y === x;
// convert x and y into numbers if they are not already use the "+" trick
if(typeof x !== "number") x = +x;
if(typeof y !== "number") y = +y;
return x === y;
}
function toPrimitive(obj) {
var value = obj.valueOf();
if(obj !== value) return value;
return obj.toString();
}
As you can see == has a lot of complicated logic for type conversion. Because of that it's hard to predict what result you are going to get.
Here are some examples of some results you wouldn't expect:
Unexpected Truths
[1] == true // returns true
'0' == false // returns true
[] == false // returns true
[[]] == false // returns true
[0] == false // returns true
'\r\n\t' == 0 // returns true
Unexpected Conclusions
// IF an empty string '' is equal to the number zero (0)
'' == 0 // return true
// AND the string zero '0' is equal to the number zero (0)
'0' == 0 // return true
// THEN an empty string must be equal to the string zero '0'
'' == '0' // returns **FALSE**
Objects with Special Functions
// Below are examples of objects that
// implement `valueOf()` and `toString()`
var objTest = {
toString: function() {
return "test";
}
};
var obj100 = {
valueOf: function() {
return 100;
}
};
var objTest100 = {
toString: function() {
return "test";
},
valueOf: function() {
return 100;
}
};
objTest == "test" // returns true
obj100 == 100 // returns true
objTest100 == 100 // returns true
objTest100 == "test" // returns **FALSE**

Categories

Resources