What is this practice called? `objectName && objectName.thing` - javascript

I'm trying to find the name of the practice (in any language) in which one checks for an object to be in existence before performing a lookup on it. Usually this is done by throwing in an && in between the object and the object lookup expression, like so in JS:
var example = objectName && objectName.thing;
such that example is evaluated to either undefined or objectName.thing, and avoids a runtime error.
I could have sworn I've heard this before, but I've completely forgotten. What is this practice called?

This is sometimes called a "guard," since the truthiness of the left operand guards access to the right operand. Of course, it's just a logical AND, but the use of AND in this specific context is occasionally called a "guard".
From Douglas Crockford's A Survey of the JavaScript Programming Language:
The && operator is commonly called logical and. It can also be called guard.
From Guard and Default Operators of JavaScript by Sean McArthur:
In Javascript, the way the languages determines logical operations and the values Javascript treats as true or false lead to people using the AND and OR operators for guard and default situations

This practice is sometimes called validation, or evaluation. You can use a ternary operator to do so.
var example = objectName ? objectName.thing : null
This will assign objectName.thing or null to example depending on objectExample

Related

Why use triple-equal (===) in TypeScript?

In JavaScript, it's commonly seen as best practice to use === instead of ==, for obvious and well-known reasons.
In TypeScript, which is one to be preferred? Is there even one which is preferable to the other one?
IMHO, using === in TypeScript doesn't make sense, since comparison already only works on equal types, hence you won't have the (more or less funny) coercion game as in plain JavaScript. If you take aside compatibility to JavaScript for a minute, TypeScript could even get rid of ===, couldn't it?
short version:
== can do unexpected type conversions, in Javascript 1=="1" is true. The === operator avoids this. Comparing different types with === is always false.
The typescript compiler will emit an error message when you compare different types with ==. This removes the unexpected type conversions that can happen with == in Javascript.
This is a case where valid Javascript leads to an error message in the typescript compiler. The idea that all valid Javascript is also valid Typescript is a common misconception. This is simply not true.
longer version:
I think the accepted answer is misleading. Typescript actually does fix == vs === (as far as possible at least).
In Javascript there are two comparison operators:
== : When comparing primitive values, like numbers and strings, this operator will apply a type conversion before doing the comparison. 1 == "1" evaluates to true.
===: This operator does not do type conversions. If the types don't match it will always return false.
Also, both operators will compare reference types based on their references. Two separate objects are never considered equal to each other, even if they store the same values:
let a = {val:1};
let b = {val:1};
c = a;
a==b; // false
a===b; // false
a==c; //true
a===c; //true
So there you have the two common sources of errors in Javascript comparisons:
comparing different types with == can lead to unexpected type conversions.
comparing objects and arrays is based on references not values stored inside.
As the existing answer already says, Typescript is designed as a superset of Javascript. So it doesn't change the behaviour of these comparison operators. If you write == in Typescript, you get type conversions.
So how is this fixed? With the compiler. If you actually do write code that compares incompatible types with == it's a compiler error. Try compiling the following sample:
let str = "1";
let num = 1;
console.log(str == num);
The compiler will tell you:
comparisons.ts:4:13 - error TS2367: This condition will always return 'false' since the types 'string' and 'number' have no overlap.
4 console.log(str == num);
~~~~~~~~~~
Found 1 error.
It is a common misconception that any valid Javascript is also valid Typescript. This is not true and the code above is an example where the typescript compiler will complain about valid Javascript.
This fixes the first of the two sources of errors: unexpected type conversions. It doesn't deal with the second source of errors: comparisons based on references. As far as I know, when you want to do a comparison based on values stored by the objects, you simply can't use these operators. You'll have to implement your own equals() method.
Also, you may have noticed that the compiler error is wrong. The comparison will not always evaluate to false. I think this is a bug in typescript and have filed an issue.
Imagine you're designing TypeScript from scratch. Essentially, you're trying to optimize for making safer code easier to write (TypeScript design goal 1) with a few caveats which prevent you from doing everything you'd like.
JavaScript compatibility (TypeScript design goal 7)
JavaScript should be valid Typescript with no changes.
CoffeeScript makes no guarantees regarding this, so it can convert all instances of == to === and simply tell users don't rely on =='s behavior. TypeScript cannot redefine == without breaking all JavaScript code that relies on its behavior (despite this having sad implications for 3).
This also implies that TypeScript cannot change the functionality of === to, for example, check the types of both operands at compile time and reject programs comparing variables of different types.
Further, compatibility is not limited to simply JavaScript programs; breaking compatibility also affects JavaScript programmers by breaking their assumptions about the differences between == and ===. See TypeScript non-goal number 7:
Introduce behaviour that is likely to surprise users. Instead have due consideration for patterns adopted by other commonly-used languages.
JavaScript as the target of compilation (TypeScript design goal 4)
All TypeScript must be representable in JavaScript. Further, it should be idiomatic JavaScript where possible.
Really though, the TypeScript compiler could use methods returning booleans for all comparisons, doing away with == and === entirely. This might even be safer for users: define a type-safe equality method on each TypeScript type (rather like C++ operator==, just without overloading).
So there is a workaround (for users comparing classes). unknown or any variables can have their types narrowed before using the type-safe equality method.
Which to prefer
Use === everywhere you would in JavaScript. This has the advantage of avoiding the pitfalls common to ==, and doesn't require you to maintain an additional method. The output of the TypeScript compiler will be close to idiomatic JavaScript. Using == has very much the same pitfalls as JavaScript, particularly when you have any, [], or {} involved. As an exception, using == null to check for null or undefined may save headaches if library code is inconsistent.
A method for reference equality (behavior like === for classes) could be confused with a deep/value recursive equality check. Furthermore, === is widely used in TypeScript, and making your code fall in line with conventions is usually more important than any small bit of type safety.
Your intuition was correct. There's no sense to use === in TypeScript to imitate an equality check. The argument that TS compiles to JS "so you should use what is better in JS" is not valid. Why? Because Typescript ensures that both operands of comparison operator(s) have the same type. When both operands have the same type == and === behave identically. And by "identically" I mean 100% identical not just "alike". So there's no more correct or less correct version when both behave exactly the same way in JavaScript.
I guess other commenters here are just looking for ways to preserve their habit of using === or in other words to rationalize. Unfortunately, pure logic tells otherwise: there's no sense to replace == with ===, unless you're going to modify generated JS code manually which is probably never the case.
I use === exclusively for identity checks (when you compare x to x – the same variables, it's sometimes necessary in library code related to memoization). And my counter of errors related to eqeq operator shows 0.
Example:
const s : string = "s"
const n : number = 1
console.log(s == n)
TS2367: This condition will always return 'false' since the types 'string'
and 'number' have no overlap
My opinion is that one should always use ===.
First line of reasoning: TypeScript does not change == to ===. There're TypeScript translators which just strip types. So using === everywhere leads to more robust code if for some reason you forgot to type check your program or if you (or future maintainer of your code) used type casts to override type safety. Should not happen but many things should not happen.
Second line of reasoning: null == undefined. This is true with TypeScript as well. I think that if one writes if (x == null) it makes code less readable because it implies check for undefined as well and implicit code is less readable than explicit if (x === null || x === undefined). Also subtle bugs might occur if this is not done on purpose.
I don't see any issues when just using === everywhere unconditionally other than aesthetic preferences.

Is there a word that covers both Null and Undefined?

I sometimes have to write code in JavaScript that handles both null and undefined the same way. For example, a function that removes from an array every item that is either null or undefined. How should I name the function?
removeNullAndUndefined is very long. removeNull is short but imprecise. Ideally I want to name it removeX, where X has the meaning "null or undefined".
Does anyone know a good word for X?
Yes: Nullish. For instance, in the current Stage 3 Nullish Coalescing Operator proposal.
So: removeNullish or similar.
When I need to check for null or undefined I often name such function either isNil or isNothing e.g.
const isNil = thing => thing === null || thing === undefined;
If you must adopt a naming convention I'd opt for what's quite common to see in functional programming, namely the Maybe monad which comes with a subtype to represent nothing: Nothing or None.
If you look at monetjs:
The Maybe type is the most common way of representing nothingness (or the null type) with making the possibilities of NullPointer issues disappear.
Maybe is effectively abstract and has two concrete subtypes: Some (also Just) and None (also Nothing).
Under the hood, it uses a isNothing function for checking for null or undefined
In ramda.js, such function is called isNil:
Checks if the input value is null or undefined
(Lodash has a similar method with the exact same name.)

Question mark syntax from CoffeeScript without CoffeeScript

CoffeeScript has such syntax sugar:
item.getFoo?().fooParam?.bar
Which translates into long javascript equivalent with getFoo==null and fooParam==null checks. The question is: are there any ways to use this syntax in vanilla javascript with a library/translator/compiler other than CoffeeScript? We use Traceur in our project, but it doesn't have such syntax because it is not ES6 compliant (although I wish it to). Maybe some way to implement it within Traceur fork?
If you don't want the exact CoffeeScript semantics, you can cheat a bit:
return item.getFoo ? (item.getFoo().fooParam || {}).bar : undefined;
There are a few tricks going on here.
The ternary operator is used to test the truthiness of item.getFoo
If fooParam is missing, falsey, or absent, we substitute it with an empty object. CoffeeScript would have bailed out here.
We return the value of bar regardless of whether it exists. If it does exist, you get the value you want. If it doesn't exist but fooParam is set, you get undefined. If it doesn't exist because fooParam was undefined and we fell back to {}, you still get undefined.
You can write some helpers if the ternary operator gets in the way:
function defaultObject(input) { // A helper to put somewhere
return input || {};
}
return defaultObject((item.getFoo || defaultObject)().fooParam).bar;
This is even trickier: defaultObject will return {} when called with getFoo, so you don't need a ternary operator around the function call. If fooParam isn't truthy, defaultObject will return another empty object, eliminating the need for another ||. If fooParam is truthy, defaultObject behaves like the identity function and returns it.
I'm sure this could be golfed further down, but I'd recommend avoiding this pattern. Anyone reading your code will be fairly confused and blame you for making a mess in the codebase.
I had this same question recently, and I came here hoping for a better solution than my current one. If you're doing this frequently, it's easier to make a function to do it for you:
var qm = function(arg) {
if (arg instanceof Object) return arg;
return function(){};
};
Then to use it, you wrap your objects in it to make sure no error is raised. It starts to look ugly if there are many question marks on a line
qm(qm(item.getFoo)().fooParam).bar
The optional chaining operator ?. was introduced in ES2020.
obj.val?.prop
obj.val?.[expr]
obj.arr?.[index]
obj.func?.(args)
It is supported by the browsers of 91.81% of internet users as of 29 November 2021 according to https://caniuse.com/mdn-javascript_operators_optional_chaining.

Should I use CoffeeScript soaks and the existential operator together?

I'm working on a script that accepts a settings object, but uses default values where settings are not provided.
I just wrote the following line of CoffeeScript:
iframe_width = settings?.iframe?.width? ? $iframe_body.width()
My intent, in plain English, is:
If the settings object is defined, and it defines a property iframe, and the iframe property defines a property width, then assign the value of the latter property to the variable iframe_width. Otherwise, assign the value returned by calling $iframe_body.width().
Does my CoffeeScript code reflect my intent, and is it the most effective way to express that? It seems awkward with all of the existential operators (?), so I wanted to put it out there for some feedback (the compiled JavaScript is very terse and cryptic, so it's hard to tell if should work as intended).
Also, I'm not sure whether there's any redundancy in using both the standard existential operator (?) and its accessor variant (?.) together.
Thanks!
Update:
The code above doesn't seem to work as expected; however, this does:
iframe_width = settings?.iframe?.width ? $iframe_body.width()
That makes sense, since I don't think the former code actually accesses the width property, but rather just checks for its existence (twice, even?). In this code, I removed the ? just after the width property, since I think that's redundant with the ? operator between the two expressions. Does that seem correct?
(Note: This answer was written before the question was updated. As the questioner realized, foo? ? bar isn't just redundant—it actually won't work, because foo? evaluates to true or false, and is therefore always non-null.)
You have two good options for simplifying this: One, you could replace the existential binary operator with an or:
iframe_width = settings?.iframe?.width? or $iframe_body.width()
Two, you could ditch the ? after width—it's redundant:
iframe_width = settings?.iframe?.width ? $iframe_body.width()
Now, you could do both if and only if iframe.width will never be 0 (since 0 or x is x). If you can be sure of that, go ahead and make it
iframe_width = settings?.iframe?.width or $iframe_body.width()

Why typeof is called operator instead of function?

While reading this article (Special Operators) in MDC, I got a question like why typeof, new, etc. are called operators?
I have a conception say + is a operator because it operators on two entities like 2+3 and gives another value.
Ofcourse functions also operates on say two entities like the same way.
Then what is difference?
Thanks for any answers.
No, being an operator isn't about whether or not it's got two operands - that's the difference between a unary operator and a binary operator (and then there's the conditional operator with three operands, which is an example of a ternary operator). For example, + can also be a unary operator:
var x = +5;
You can sort of thing of operators as "built-in functions". They're known about by the JavaScript engine itself, and are part of the language rather than just being library features. (Although operators can often be overloaded by libraries, depending on the language. I don't know if JavaScript supports operator overloading, offhand.)
In some cases (JavaScript being an example) there's a bit of a blurring between the language and the standard library, but think about what typeof takes as an operand: it's the name of a type. That's not something you can use normally as a function argument; it needs special support in the language.
++ is also an operator with only one argument.
One of the differences is that you don't call an operator with parameters, i.e you write typeof a or new SomeObject(), whereas a function type_of would be called with type_of(a). But like Jon said, you can kind of think of them as built-in functions. As a side note () in myFunc(arg1, arg2) is a function-application operator, i.e it invokes a function with the arguments given.

Categories