What does "?" interrogation mean in accessing the properties of an object?

Asked

Viewed 528 times

7

I have already used ternary operators to carry out this type of verification:

route.params.userUpdated ? route.params.userUpdated : undefined;

But I’ve never seen anything like it:

route.params?.userUpdated;

What exactly does this ?.?

  • 1

    Follow DOC https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining

1 answer

12

It’s called optional chaining (optional chaining). It was introduced in Ecmascript 2020.

Is analogous to the operator ., so that allows you to access properties of objects. The difference is that it will not throw an error if you try to access a property nullish (null or undefined).

See the difference:

const obj = {
  person: {
    name: 'Foo',
    age: 50
  }
};

console.log(obj.person?.name); //=> Foo
console.log(obj.person.name); //=> Foo

console.log(obj.dontExist?.foo); //=> undefined
console.log(objdontExist.foo); //=> BOM! TypeError


But it is not limited to "static access". You can use it in several situations:

Access object properties (analogous to point notation)

We’ve seen this example before. The syntax is this:

obj.val?.prop

Thus, if val for null or undefined, the code will not launch a TypeError. The expression will simply evaluate to undefined. If val is an object, access will normally occur, comparable to using the ..

Dynamically access object properties (analogous to bracket notation)

The syntax is this:

obj.val?.[expr]
obj.arr?.[index]

It is similar to the previous one, but the bracket is used to search for a "dynamic" key - the result of an expression. You can use symbols or numbers as well.

The operation is the same - if the object you try to access is nullish, the expression will return undefined instead of throwing the error. Otherwise, the property will be searched for by key resulting from the expression inside the brackets normally. You can also use this to try to access an index for a possible array. If it is null and you are using optional chaining no error will be launched.

Examples:

const obj = { a: 1, b: 2 };
const arr = [1, 2, 3];

console.log(obj?.['b']); //=> 2
console.log(arr?.[2]); //=> 3

console.log(obj.null?.['prop']); //=> undefined
console.log(obj.undefinedArr?.[0]); //=> undefined

Optionally apply function

The syntax is this:

obj.func?.(args)

In that case, if obj.func is a function, it will be called normally. If obj.func for nullish, the application will not occur and the expression will return undefined.

Be careful with this scenario: The "optional application" will only occur if obj.func for nullish. If any value (no nullish) that does not implement [[Call]] (that is, it cannot be called as a function), you will receive a TypeError, once tried to call a value that is not function.

Examples:

const obj = {
  fn: function() {
    return 5;
  },
  
  str: 'Hello'
};

console.log(obj.fn?.()); //=> 5
console.log(obj.undefinedFn?.()); //=> undefined
console.log(obj.str?.()); //=> BOM! TypeError


Addendum: Null coalescence operator

As the optional chaining ensures that no errors will be launched through simple access to object properties, it matches extremely well with the null coalescence operator (??), which was also introduced in ES2020.

It short-circuits only if the first operand is null or undefined (possible results of optional chaining "failure"):

const obj = {
  foo: {
    qux: false
  }
};

console.log(obj.foo?.bar?.baz ?? 'Valor padrão'); //=> Valor padrão
console.log(obj.foo?.qux ?? 'Valor padrão'); //=> false

  • 1

    I knew Typescript, I didn’t know I’d already reached Ecmascript

Browser other questions tagged

You are not signed in. Login or sign up in order to post.