Can I convert a string representing a boolean value (e.g., 'true', 'false') into a intrinsic type in JavaScript?
I have a hidden form in HTML that is updated based upon a user's selection within a list. This form contains some fields which represent boolean values and are dynamically populated with an intrinsic boolean value. However, once this value is placed into the hidden input field it becomes a string.
The only way I could find to determine the field's boolean value, once it was converted into a string, was to depend upon the literal value of its string representation.
var myValue = document.myForm.IS_TRUE.value;
var isTrueSet = myValue == 'true';
Is there a better way to accomplish this?
Do:
var isTrueSet = (myValue === 'true');
using the identity operator (===), which doesn't make any implicit type conversions when the compared variables have different types.
This will set isTrueSet to a boolean true if the string is "true" and boolean false if it is string "false" or not set at all.
For making it case-insensitive, try:
var isTrueSet = /^true$/i.test(myValue);
// or
var isTrueSet = (myValue?.toLowerCase?.() === 'true');
// or
var isTrueSet = (String(myValue).toLowerCase() === 'true');
Don't:
You should probably be cautious about using these two methods for your specific needs:
var myBool = Boolean("false"); // == true
var myBool = !!"false"; // == true
Any string which isn't the empty string will evaluate to true by using them. Although they're the cleanest methods I can think of concerning to boolean conversion, I think they're not what you're looking for.
Warning
This highly upvoted legacy answer is technically correct but only covers a very specific scenario, when your string value is EXACTLY "true" or "false".
An invalid json string passed into these functions below WILL throw an exception.
Original answer:
How about?
JSON.parse("True".toLowerCase());
or with jQuery
$.parseJSON("TRUE".toLowerCase());
const stringToBoolean = (stringValue) => {
switch(stringValue?.toLowerCase()?.trim()){
case "true":
case "yes":
case "1":
return true;
case "false":
case "no":
case "0":
case null:
case undefined:
return false;
default:
return JSON.parse(stringValue);
}
}
I think this is much universal:
if (String(a).toLowerCase() == "true") ...
It goes:
String(true) == "true" //returns true
String(false) == "true" //returns false
String("true") == "true" //returns true
String("false") == "true" //returns false
Remember to match case:
var isTrueSet = (myValue.toLowerCase() === 'true');
Also, if it's a form element checkbox, you can also detect if the checkbox is checked:
var isTrueSet = document.myForm.IS_TRUE.checked;
Assuming that if it is checked, it is "set" equal to true. This evaluates as true/false.
This is the easiest way to do boolean conversion I came across recently. Thought of adding it.
JSON.parse('true');
let trueResponse = JSON.parse('true');
let falseResponse = JSON.parse('false');
console.log(trueResponse);
console.log(falseResponse);
You can use regular expressions:
/*
* Converts a string to a bool.
*
* This conversion will:
*
* - match 'true', 'on', or '1' as true.
* - ignore all white-space padding
* - ignore capitalization (case).
*
* ' tRue ','ON', and '1 ' will all evaluate as true.
*
*/
function strToBool(s)
{
// will match one and only one of the string 'true','1', or 'on' rerardless
// of capitalization and regardless off surrounding white-space.
//
regex=/^\s*(true|1|on)\s*$/i
return regex.test(s);
}
If you like extending the String class you can do:
String.prototype.bool = function() {
return strToBool(this);
};
alert("true".bool());
For those (see the comments) that would like to extend the String object to get this but are worried about enumerability and are worried about clashing with other code that extends the String object:
Object.defineProperty(String.prototype, "com_example_bool", {
get : function() {
return (/^(true|1)$/i).test(this);
}
});
alert("true".com_example_bool);
(Won't work in older browsers of course and Firefox shows false while Opera, Chrome, Safari and IE show true. Bug 720760)
Wood-eye be careful.
After seeing the consequences after applying the top answer with 500+ upvotes, I feel obligated to post something that is actually useful:
Let's start with the shortest, but very strict way:
var str = "true";
var mybool = JSON.parse(str);
And end with a proper, more tolerant way:
var parseBool = function(str, strict)
{
// console.log(typeof str);
// strict: JSON.parse(str)
if (str == null)
{
if (strict)
throw new Error("Parameter 'str' is null or undefined.");
return false;
}
if (typeof str === 'boolean')
{
return (str === true);
}
if(typeof str === 'string')
{
if(str == "")
return false;
str = str.replace(/^\s+|\s+$/g, '');
if(str.toLowerCase() == 'true' || str.toLowerCase() == 'yes')
return true;
str = str.replace(/,/g, '.');
str = str.replace(/^\s*\-\s*/g, '-');
}
// var isNum = string.match(/^[0-9]+$/) != null;
// var isNum = /^\d+$/.test(str);
if(!isNaN(str))
return (parseFloat(str) != 0);
return false;
}
Testing:
var array_1 = new Array(true, 1, "1",-1, "-1", " - 1", "true", "TrUe", " true ", " TrUe", 1/0, "1.5", "1,5", 1.5, 5, -3, -0.1, 0.1, " - 0.1", Infinity, "Infinity", -Infinity, "-Infinity"," - Infinity", " yEs");
var array_2 = new Array(null, "", false, "false", " false ", " f alse", "FaLsE", 0, "00", "1/0", 0.0, "0.0", "0,0", "100a", "1 00", " 0 ", 0.0, "0.0", -0.0, "-0.0", " -1a ", "abc");
for(var i =0; i < array_1.length;++i){ console.log("array_1["+i+"] ("+array_1[i]+"): " + parseBool(array_1[i]));}
for(var i =0; i < array_2.length;++i){ console.log("array_2["+i+"] ("+array_2[i]+"): " + parseBool(array_2[i]));}
for(var i =0; i < array_1.length;++i){ console.log(parseBool(array_1[i]));}
for(var i =0; i < array_2.length;++i){ console.log(parseBool(array_2[i]));}
I thought that #Steven 's answer was the best one, and took care of a lot more cases than if the incoming value was just a string. I wanted to extend it a bit and offer the following:
function isTrue(value){
if (typeof(value) === 'string'){
value = value.trim().toLowerCase();
}
switch(value){
case true:
case "true":
case 1:
case "1":
case "on":
case "yes":
return true;
default:
return false;
}
}
It's not necessary to cover all the false cases if you already know all of the true cases you'd have to account for. You can pass anything into this method that could pass for a true value (or add others, it's pretty straightforward), and everything else would be considered false
Universal solution with JSON parse:
function getBool(val) {
return !!JSON.parse(String(val).toLowerCase());
}
getBool("1"); //true
getBool("0"); //false
getBool("true"); //true
getBool("false"); //false
getBool("TRUE"); //true
getBool("FALSE"); //false
UPDATE (without JSON):
function getBool(val){
var num = +val;
return !isNaN(num) ? !!num : !!String(val).toLowerCase().replace(!!0,'');
}
I also created fiddle to test it http://jsfiddle.net/remunda/2GRhG/
Your solution is fine.
Using === would just be silly in this case, as the field's value will always be a String.
The Boolean object doesn't have a 'parse' method. Boolean('false') returns true, so that won't work. !!'false' also returns true, so that won't work also.
If you want string 'true' to return boolean true and string 'false' to return boolean false, then the simplest solution is to use eval(). eval('true') returns true and eval('false') returns false.
Keep in mind the performance and security implications when using eval() though.
var falsy = /^(?:f(?:alse)?|no?|0+)$/i;
Boolean.parse = function(val) {
return !falsy.test(val) && !!val;
};
This returns false for every falsy value and true for every truthy value except for 'false', 'f', 'no', 'n', and '0' (case-insensitive).
// False
Boolean.parse(false);
Boolean.parse('false');
Boolean.parse('False');
Boolean.parse('FALSE');
Boolean.parse('f');
Boolean.parse('F');
Boolean.parse('no');
Boolean.parse('No');
Boolean.parse('NO');
Boolean.parse('n');
Boolean.parse('N');
Boolean.parse('0');
Boolean.parse('');
Boolean.parse(0);
Boolean.parse(null);
Boolean.parse(undefined);
Boolean.parse(NaN);
Boolean.parse();
//True
Boolean.parse(true);
Boolean.parse('true');
Boolean.parse('True');
Boolean.parse('t');
Boolean.parse('yes');
Boolean.parse('YES');
Boolean.parse('y');
Boolean.parse('1');
Boolean.parse('foo');
Boolean.parse({});
Boolean.parse(1);
Boolean.parse(-1);
Boolean.parse(new Date());
There are a lot of answers and it's hard to pick one. In my case, I prioritise the performance when choosing, so I create this jsPerf that I hope can throw some light here.
Brief of results (the higher the better):
Conditional statement: 2,826,922
Switch case on Bool object: 2,825,469
Casting to JSON: 1,867,774
!! conversions: 805,322
Prototype of String: 713,637
They are linked to the related answer where you can find more information (pros and cons) about each one; specially in the comments.
This has been taken from the accepted answer, but really it has a very weak point, and I am shocked how it got that count of upvotes, the problem with it that you have to consider the case of the string because this is case sensitive
var isTrueSet = (myValue.toLowerCase() === 'true');
I use the following:
function parseBool(b) {
return !(/^(false|0)$/i).test(b) && !!b;
}
This function performs the usual Boolean coercion with the exception of the strings "false" (case insensitive) and "0".
The expression you're looking for simply is
/^true$/i.test(myValue)
as in
var isTrueSet = /^true$/i.test(myValue);
This tests myValue against a regular expression , case-insensitive, and doesn't modify the prototype.
Examples:
/^true$/i.test("true"); // true
/^true$/i.test("TRUE"); // true
/^true$/i.test("tRuE"); // true
/^true$/i.test(" tRuE"); // false (notice the space at the beginning)
/^true$/i.test("untrue"); // false (some other solutions here will incorrectly return true
/^true$/i.test("false");// returns false
/^true$/i.test("xyz"); // returns false
Simplest solution 🙌🏽
with ES6+
use the logical NOT twice [ !! ] to get the string converted
Just paste this expression...
const stringToBoolean = (string) => string === 'false' ? false : !!string
And pass your string to it!
stringToBoolean('') // false
stringToBoolean('false') // false
stringToBoolean('true') // true
stringToBoolean('hello my friend!') // true
🤙🏽 Bonus! 🤙🏽
const betterStringToBoolean = (string) =>
string === 'false' || string === 'undefined' || string === 'null' || string === '0' ?
false : !!string
You can include other strings at will to easily extend the usage of this expression...:
betterStringToBoolean('undefined') // false
betterStringToBoolean('null') // false
betterStringToBoolean('0') // false
betterStringToBoolean('false') // false
betterStringToBoolean('') // false
betterStringToBoolean('true') // true
betterStringToBoolean('anything else') // true
you can use JSON.parse as follows:
var trueOrFalse='True';
result =JSON.parse(trueOrFalse.toLowerCase());
if(result==true)
alert('this is true');
else
alert('this is false');
in this case .toLowerCase is important
Boolean.parse = function (str) {
switch (str.toLowerCase ()) {
case "true":
return true;
case "false":
return false;
default:
throw new Error ("Boolean.parse: Cannot convert string to boolean.");
}
};
There are already so many answers available. But following can be useful in some scenarios.
// One can specify all values against which you consider truthy
var TRUTHY_VALUES = [true, 'true', 1];
function getBoolean(a) {
return TRUTHY_VALUES.some(function(t) {
return t === a;
});
}
This can be useful where one examples with non-boolean values.
getBoolean('aa'); // false
getBoolean(false); //false
getBoolean('false'); //false
getBoolean('true'); // true
getBoolean(true); // true
getBoolean(1); // true
To convert both string("true", "false") and boolean to boolean
('' + flag) === "true"
Where flag can be
var flag = true
var flag = "true"
var flag = false
var flag = "false"
I'm suprised that includes was not suggested
let bool = "false"
bool = !["false", "0", 0].includes(bool)
You can modify the check for truely or include more conditions (e.g. null, '').
This function can handle string as well as Boolean true/false.
function stringToBoolean(val){
var a = {
'true':true,
'false':false
};
return a[val];
}
Demonstration below:
function stringToBoolean(val) {
var a = {
'true': true,
'false': false
};
return a[val];
}
console.log(stringToBoolean("true"));
console.log(typeof(stringToBoolean("true")));
console.log(stringToBoolean("false"));
console.log(typeof(stringToBoolean("false")));
console.log(stringToBoolean(true));
console.log(typeof(stringToBoolean(true)));
console.log(stringToBoolean(false));
console.log(typeof(stringToBoolean(false)));
console.log("=============================================");
// what if value was undefined?
console.log("undefined result: " + stringToBoolean(undefined));
console.log("type of undefined result: " + typeof(stringToBoolean(undefined)));
console.log("=============================================");
// what if value was an unrelated string?
console.log("unrelated string result: " + stringToBoolean("hello world"));
console.log("type of unrelated string result: " + typeof(stringToBoolean(undefined)));
One Liner
We just need to account for the "false" string since any other string (including "true") is already true.
function b(v){ return v==="false" ? false : !!v; }
Test
b(true) //true
b('true') //true
b(false) //false
b('false') //false
A more exaustive version
function bool(v){ return v==="false" || v==="null" || v==="NaN" || v==="undefined" || v==="0" ? false : !!v; }
Test
bool(true) //true
bool("true") //true
bool(1) //true
bool("1") //true
bool("hello") //true
bool(false) //false
bool("false") //false
bool(0) //false
bool("0") //false
bool(null) //false
bool("null") //false
bool(NaN) //false
bool("NaN") //false
bool(undefined) //false
bool("undefined") //false
bool("") //false
bool([]) //true
bool({}) //true
bool(alert) //true
bool(window) //true
I'm using this one
String.prototype.maybeBool = function(){
if ( ["yes", "true", "1", "on"].indexOf( this.toLowerCase() ) !== -1 ) return true;
if ( ["no", "false", "0", "off"].indexOf( this.toLowerCase() ) !== -1 ) return false;
return this;
}
"on".maybeBool(); //returns true;
"off".maybeBool(); //returns false;
"I like js".maybeBool(); //returns "I like js"
why don't you try something like this
Boolean(JSON.parse((yourString.toString()).toLowerCase()));
It will return an error when some other text is given rather than true or false regardless of the case and it will capture the numbers also as
// 0-> false
// any other number -> true
You need to separate (in your thinking) the value of your selections and the representation of that value.
Pick a point in the JavaScript logic where they need to transition from string sentinels to native type and do a comparison there, preferably where it only gets done once for each value that needs to be converted. Remember to address what needs to happen if the string sentinel is not one the script knows (i.e. do you default to true or to false?)
In other words, yes, you need to depend on the string's value. :-)
Hands down the easiest way (assuming you string will be 'true' or 'false') is:
var z = 'true';
var y = 'false';
var b = (z === 'true'); // will evaluate to true
var c = (y === 'true'); // will evaluate to false
Always use the === operator instead of the == operator for these types of conversions!
Like #Shadow2531 said, you can't just convert it directly. I'd also suggest that you consider string inputs besides "true" and "false" that are 'truthy' and 'falsey' if your code is going to be reused/used by others. This is what I use:
function parseBoolean(string) {
switch (String(string).toLowerCase()) {
case "true":
case "1":
case "yes":
case "y":
return true;
case "false":
case "0":
case "no":
case "n":
return false;
default:
//you could throw an error, but 'undefined' seems a more logical reply
return undefined;
}
}
I am attempting to solve a generic Palindrome problem recursively. However, it seems that my algorithm is only evaluating the first recursive call, not the second, which should check all characters in the string. There is apparently a logic error in my algorithm, but I can't spot it. Can anyone advise? See the code below.
function isPalindrome(totalChars: number, lastIdx: number, str: string): boolean | undefined {
console.log(`lastIdx: ${lastIdx}; char: ${str[lastIdx]}`);
// const curIdx = lastIdx;
let highIdx = lastIdx;
const lowIdx = totalChars-1 - highIdx;
// Base Case:
if(totalChars === 0) return true;
if (lowIdx === highIdx) return true;
if (lowIdx > highIdx) {
console.log(`Endpoint reached; STR: ${str}; LOW: ${str[lowIdx]}; high: ${str[highIdx]}`);
return;
}
if(str[lowIdx] === str[highIdx]) {
console.log(`Loop through idx; STR: ${str}; LOW: ${str[lowIdx]}; high: ${str[highIdx]}`);
return true;
}
else if(str[lowIdx] !== str[highIdx]) return false;
// Recursive Case:
return isPalindrome(totalChars, highIdx, str) && isPalindrome(totalChars, highIdx-1, str);
}
// console.log("a is Palindrome: " + isPalindrome("a".length, "a".length-1, "a"));
// console.log("motor is Palindrome: " + isPalindrome("motor".length, "motor".length-1,"motor"));
console.log("rotor is Palindrome: " + isPalindrome("rotor".length, "rotor".length-1,"rotor"));
There are a few problems:
your if...else will always result in a return, and so the statement with the recursive call will never be executed.
Note that the condition after else if will always be true when it gets evaluated, since it is the negation of the condition that is evaluated in the earlier if statement.
More importantly, when that earlier if condition is true, you don't want to return, as it has not been verified yet that the remaining (inner) characters match. This still has to be verified via the recursive call, so this is not a place to perform a return. Just remove that if block, and only return when the characters differ.
So replace this:
if(str[lowIdx] === str[highIdx])
{
return true;
}
else if(str[lowIdx] !== str[highIdx]) return false;
With just:
if(str[lowIdx] !== str[highIdx]) return false;
The first recursive call passes the same arguments as the current execution of the function got -- this will lead to infinite recursion. A recursive call must always make the problem smaller. In this case, there is actually no need to make two recursive calls, and you should remove that first one.
So replace this:
return isPalindrome(totalChars, highIdx, str) && isPalindrome(totalChars, highIdx-1, str);
with:
return isPalindrome(totalChars, highIdx-1, str);
The base case has a condition where return is executed without boolean return value. The function should always return a boolean value. In this case it should be true, because it means that all character-pairs were compared, and there is no single-middle character remaining (the size of the string is even). So you can combine this case with the previous base case. In fact, that base case condition will also work when totalChars is zero, so you can omit that first if.
So change this:
if (totalChars === 0) return true;
if (lowIdx === highIdx) return true;
if (lowIdx > highIdx) {
return;
}
with:
if (lowIdx >= highIdx) return true;
I am attempting to solve this codewars problem:
Complete the function scramble(str1, str2) that returns true if a
portion of str1 characters can be rearranged to match str2, otherwise
returns false.
examples:
scramble('rkqodlw', 'world') ==> True
scramble('cedewaraaossoqqyt', 'codewars') ==> True
scramble('katas', 'steak') ==> False
This is my attempt:
function scramble(str1, str2) {
let obj1 = {};
let obj2 = {};
for (el of str1) {
obj1[el] = (obj1[el] || 0) + 1;
}
for (el of str2) {
obj2[el] = (obj2[el] || 0) + 1;
}
for (el in obj2) {
if (!(el in obj1)) return false;
}
return true;
}
I am converting the strings to objects, and then comparing the keys to each other. My code passes about 90% of all the tests on Codewars, but then it does not pass the other 10% and they do not show what the test inputs are unfortunately.
My hunch is that there are a few edge cases that this code is not catching. Any help would be appreciated.
You will need to handle the case when str2 has more instances of a letter than str1.
For example:
scramble("a", "aa")
Which should evaluate to false (not enough 'a's in "a" to form "aa").
You need to handle the amount of characters. Now you just checking whether the character in str2 also exists in str1.
So instead of:
for (el in obj2) {
if (!(el in obj1)) return false;
}
Try:
for (let [key, value] of Object.entries(obj2)) {
if (obj1[key] === undefined || obj1[key] < value) return false;
}
Which means that if obj1[key] doesn't exist or it has less occurrences than obj2[key] it will return false.
this code maybe helps
function scramble(str1, str2) {
let occurences = str1.split("").reduce((arr, cur) => { arr[cur] ? arr[cur]++ : arr[cur] = 1; return arr; }, {});
console.log(occurences);
return str2.split("").every((character) => --occurences[character] >= 0);
}
console.log(scramble("awpoirwled", "world"));
The algorithm I would use is to take each letter of the match string, and if its got an equivalent in the searched string, remove it from there and continue, otherwise abort if there is no match.
If you reach the end of the match string without aborting then you have a match
For example, can I create a method which can return me an expression that can be evaluated by if?
function getCondition(variable, value, operator)//not sure what params to pass
{
var condition = false; //initialized to false
//generate condition based on parameter passed
return condition;
}
and then use it directly
if ( getCondition( a, 5, "<" ) ){ console.log("correct") }
Yes.
In your example, which probably is not your actual use-case, you'd simply have to map your operator:
function getCondition( x, y, op ) {
switch ( op ) {
case '<':
return x < y
case '>':
return x > y
default:
throw new Error( 'operator not understood' )
}
}
if ( getCondition( 1, 5, '<' ) ) {
...
}
You might see this pattern commonly in something like a physics simulation, where you need operators that do not exist natively, such as dot or cross products. I've never seen a use-case where you'd want to pass that operator explicitly to a function though, rather, just create the functions you need for each operator.
You could pass the expression as a parameter
var a = 3.5;
function getCondition(bool) {
var condition = false;
return bool || condition
}
if (getCondition(a < 5)) {
console.log("correct")
}
You probably want to evaluate arguments when you apply the condition, not when you define it. Here's one possibility:
var operator = {};
operator.greaterThan = function(val) {
return function(x) {
return x > val;
}
};
operator.lessThan = function(val) {
return function(x) {
return x < val;
}
};
isLessThan5 = operator.lessThan(5);
a = 4;
if(isLessThan5(a)) console.log('ok'); else console.log('not ok');
b = 10;
if(isLessThan5(b)) console.log('ok'); else console.log('not ok');
For complex conditions you can also add boolean operators:
operator.and = function() {
var fns = [].slice.call(arguments);
return function(x) {
return fns.every(f => f(x));
}
};
operator.or = function() {
var fns = [].slice.call(arguments);
return function(x) {
return fns.some(f => f(x));
}
};
isBetween5and10 = operator.and(
operator.greaterThan(5),
operator.lessThan(10));
if(isBetween5and10(8)) console.log('ok')
if(isBetween5and10(15)) console.log('ok')
Yes, but you have to define in the function what the operator means. So your function needs to contain some code along the lines of:
if (operator === '>') {
condition = (value1 > value2);
}
You could also use string concatenation and eval, but I wouldn't recommend it:
condition = eval(value1 + operator + value2);
Yes, you can use the return value of a method if it can be evaluated to either true or false.
The sample code you provided should work as you expect it.
The return value of the method can also be evaluated from an int or a string to a boolean value. Read more about that here: JS Type Coercion
It is possible to pass a function or expression to an if. Like you're saying yourself, an if accepts an expression... that evaluates to either true or false. So you can create any function or method that returns a boolean value (not entirely true in PHP and other weak typed languages).
Clearly, since PHP isn't strongly typed, no function guarantees that it returns a boolean value, so you need to implement this properly yourself, as doing this makes you prone to getting errors.
I execute some function and get a return value. This value could be anything (string, array, object, reference, function). I then pass this result along using JSON.stringify.
Now, the functions and references don't do me much good in the scope they're being delivered to, so the whole "to string, eval" method isn't much use. I'm going to store them in a local array and just pass along an ID to reference them by later. But, I do go ahead and send string data, arrays, and objects (in the "associated array" sense of javascript objects) as those all play very nicely with JSON.stringify.
I'm already using try... JSON.stringify() catch to do this with recursive objects (which JSON.stringify errors on.) But that doesn't account for anything else mentioned above.
What is the most efficient way to check if an value contains a function?
And not
typeof foo === "function"
Because the return might be
["foo", "bar", ["foo", "bar"], function(){...something}]
I don't want to pick apart each individual piece's type either, just return on the whole whether there's ANY functions/objects that cannot be safely stringified. I could probably work out how to loop and check each individual value, but if there's a shortcut or more efficient method someone can think of, I'd like to hear it.
Thanks!
Refining welcome and appreciated!
//your favorite object length checking function could go here
$.objectLength = (function(){
//ie<9
if (typeof Object.keys === "undefined" ){
return function(o){
var count = 0, i;
for (i in o) {
if (o.hasOwnProperty(i)) {
count++;
}
}
return count;
};
//everyone else
} else {
return function(o){
return Object.keys(o).length;
}
}
})();
//comparing our two objects
$.checkMatch = function(a, b){
//if they're not the same length, we're done here. (functions exist, etc)
if (typeof a !== typeof b || typeof a === "object" && typeof b === "object" && a && b && $.objectLength(a) !== $.objectLength(b)){
return false;
//if they are the same length, they may contain deeper objects we need to check.
} else {
var key;
for (key in a){
//make sure it's not prototyped key
if (a.hasOwnProperty(key)){
//if it doesn't exist on the other object
if (!b.hasOwnProperty(key)){
return false;
//if this an object as well
} else if (typeof a[key] === "object"){
//check for a match
if (!$.checkMatch(a[key], b[key])){
return false;
}
//then check if they're not equal (simple values)
} else if (a[key] !== b[key]){
return false
}
}
}
return true;
}
};
//...stuff
//catch recursive objects in parameters
var good = true, sendObject = {"ourobject", "values"}, finalSendObject;
//try to stringify, which rejects infinitely recursive objects
try {
finalSendObject = JSON.stringify(sendObject);
} catch(e){
good = false;
}
//if that passes, try matching the original against the parsed JSON string
if (good && sendObject !== JSON.parse(finalSendObject)){
good = $.checkMatch(sendObject, JSON.parse(finalSendObject));
}
This will not work
But I will leave it up for anyone who thinks of trying it. Working solution coming shortly.
30 seconds later, I figure it out myself.
String it, parse it. If anything changed, it wont be equal to itself.
var checkParse = function(obj){
return obj === JSON.parse(JSON.strigify(obj));
}