Here are some javascript tips on property check, string comparison & check for defined that you can use in your code.
Property check
We know that the method hasOwnProperty()
can be used for checking whether a property exists in an object like the code below.
let object = { x: 1, y: 2 };
console.log(object.hasOwnProperty("x")); // true
console.log(object.hasOwnProperty("z")); // false
console.log(object.hasOwnProperty("toString")); //false
You can see that hasOwnProperty()
does not check the existence of inherited properties like toString()
in an object.
An alternative is to use the in
operator. I find it much shorter and can come in handy when one needs to check inherited properties.
let object = { x: 1, y: 2 };
console.log("x" in object); //true
console.log("z" in object); // false
console.log("toString" in object); //true
Below is how in
operator works in arrays.
let array = ["x", "y", "z"];
console.log("x" in array); //false
console.log("toString" in array); //true
console.log("0" in array); //true - index element 0
String comparison
Normally we compare strings using the <
, >
or ===
operators like below
console.log("zoo" < "ant"); // false - 'ant' comes before 'zoo'
Note that JavaScript strings are sequences of 16-bit integer values and string comparison is just a numerical comparison of the values in the two strings, that results in capital ASCII letters being “less than” all lowercase ASCII letters.
console.log("Zoo" < "ant"); // true - 'Zoo' comes before 'ant'
Therefore most developers follow the approach of converting the strings into either lowerCase or upperCase before comparing or sorting.
console.log("Zoo".toLowerCase() < "ant"); // false - now 'ant' comes before 'Zoo'
But things are not so simple in other languages. Spanish, for example treats ñ as a distinct letter that comes after n and before o. Lithuanian alphabetizes Y before J, and Welsh treats digraphs like CH and DD as single letters with CH coming after C and DD sorting after D.
String.localeCompare()
takes locale-specific definitions of alphabetical order into account. For example
let items = ['réservé', 'Premier', 'Cliché', 'communiqué', 'café', 'Adieu'];
items.sort( (a, b) => a.localeCompare(b, 'fr', {ignorePunctuation: true}));
console.log(items);// ['Adieu', 'café', 'Cliché', 'communiqué', 'Premier', 'réservé']
But if you want to compare large arrays of language sensitive strings, it is better to use Into.collator
constructor as it is more performant.
console.log(['Z', 'a', 'z', 'ä'].sort(new Intl.Collator('de').compare));
// expected output: ["a", "ä", "z", "Z"]
Refer Intl.Collator and String.localeCompare to know more.
Check for defined
Some check for defined variable or an object property in the following way
let object = { x: undefined, y: "hello" };
(object.x !== undefined || object.x !== null) ? object.x : "hi"; // "hi"
The above can be simplified by using the Logical OR (||)
operator.
let object = { x: undefined, y: "hello" };
object.x || "hi" ; // "hi"
The ||
operator returns the first truthy value found, if both operands are falsy then the falsy value is returned. Falsy values include, false, null, undefined, 0 and "".
The first example can also be simplified using a Logical AND (&&)
operator.
let object = { x: undefined, y: "hello" };
object.x && object.x || "hi" ; // "hi"
In the above code &&
operator returns true if and only if both its first operand and its second operand are true else it returns false. Here object.x && object.x
returns false and therefore the result false || "hi"
will return the truthy value i.e "hi"
.
However in certain cases we want the falsy values to be returned , for example the number 0
or the empty string ""
.
In this case, the operator ??
could be used instead. This operator returns the values that are not null
or undefined
.
let options = { timeout: 0, title: "", verbose: false, n: null };
options.timeout ?? 1000 // => 0: as defined in the object
options.title ?? "Untitled" // => "": as defined in the object
options.verbose ?? true // => false: as defined in the object
options.quiet ?? false // => false: property is not defined
options.n ?? 10 // => 10: property is null
Note that the ??
operator does not have higher precedence or lower precedence than the &&
and ||
operators, therefore you must use parenthesis explicitly.
(a ?? b) || c // ?? first, then ||
a ?? (b || c) // || first, then ??
a ?? b || c // SyntaxError: parentheses are required
To be continued ...