O Operador de Encadeamento Opcional em JavaScript
O operador ?.
, conhecido como operador de encadeamento opcional (optional chaning), permite verificar se um objeto, suas propriedades ou métodos são null
ou undefined
. Caso eles estejam definidos, o operador permite acessar suas propriedades ou métodos sem causar um erro.
Por exemplo, se temos um objeto que pode ser null
, ao tentar acessar uma propriedade diretamente, como no caso da função printName
, ocorrerá um erro se o objeto não estiver definido:
const tom = null;
const bob = { name: "Bob" };
function printName(person) {
console.log(person.name);
}
printName(tom); // Uncaught TypeError: Cannot read properties of null (reading "name")
printName(bob);
Uma maneira de evitar esse erro é verificando se o objeto não é null
ou undefined
antes de acessar a propriedade:
const tom = null;
const bob = { name: "Bob" };
function printName(person) {
if (person !== null && person !== undefined) console.log(person.name);
}
printName(tom);
printName(bob); // Bob
Também é possível simplificar essa verificação usando apenas if(person)
:
function printName(person) {
if (person) console.log(person.name);
}
No entanto, o operador ?.
oferece uma abordagem mais elegante e menos verbosa:
const tom = null;
const bob = { name: "Bob" };
function printName(person) {
console.log(person?.name);
}
printName(tom); // undefined
printName(bob); // Bob
O operador ?.
verifica se o objeto não é null
ou undefined
antes de tentar acessar a propriedade ou método especificado após o ponto. Se o objeto for null
ou undefined
, a operação é interrompida e retorna undefined
, evitando assim o erro.
Este operador pode ser usado tanto para propriedades quanto para métodos de um objeto:
const tom = undefined;
const bob = {
name: "Bob",
sayHi() {
console.log(`Hi! I am ${this.name}`);
},
};
console.log(tom?.name); // undefined
console.log(bob?.name); // Bob
tom?.sayHi(); // não executa
bob?.sayHi(); // Hi! I am Bob
Verificação de Propriedade
Um objeto pode ser definido, mas não possuir alguma propriedade:
const tom = { name: "Tom" };
const bob = {
name: "Bob",
company: {
title: "Microsoft",
},
};
console.log(tom.company?.title); // undefined
console.log(bob.company?.title); // Microsoft
Da mesma forma, podemos acessar as propriedades do objeto usando a sintaxe de arrays:
const tom = { name: "Tom" };
const bob = {
name: "Bob",
company: {
title: "Microsoft",
},
};
console.log(tom.company?.["title"]); // undefined
console.log(bob.company?.["title"]); // Microsoft
Verificação de Propriedade de Array
Similarmente, podemos verificar a existência de uma propriedade de array antes de acessar seus elementos:
const tom = { name: "Tom" };
const bob = {
name: "Bob",
languages: ["javascript", "typescript"],
};
console.log(tom.languages?.[0]); // undefined
console.log(bob.languages?.[0]); // javascript
Verificação de Método
Um objeto também pode não ter um método que pode ser chamado. Se o método não estiver definido, ao tentar acessar um método indefinido, encontraremos um erro, e neste caso também podemos verificar a existência do método:
const tom = { name: "Tom" };
const bob = {
name: "Bob",
say(words) {
console.log(words);
},
};
console.log(tom.say?.("my name is Tom")); // undefined
console.log(bob.say?.("my name is Bob")); // my name is Bob
Cadeia de Verificações
Usando o operador ?.
, podemos criar cadeias de verificações, verificando sequencialmente se o valor é null
/undefined
:
const sam = { name: "Sam" };
const tom = {
name: "Tom",
company: { title: "Google" },
};
const bob = {
name: "Bob",
company: {
title: "Microsoft",
print() {
console.log(`Empresa ${this.title}`);
},
},
};
sam?.company?.print?.(); // não é chamado - não há propriedade company
tom?.company?.print?.(); // não é chamado - não há método print
bob?.company?.print?.(); // Empresa Microsoft