If you’re looking for the JavaScript "isset" equivalent, you’ve probably used it in PHP before and want the same functionality in JavaScript.
✋ Update: This post was originally published on my blog decodingweb.dev, where you can read the latest version for a 💯 user experience. ~reza
As you probably know, PHP’s isset()
function checks a variable is declared and not null.
Although JavaScript doesn’t have an isset equivalent, there are several ways to check for the existence of a “potentially undeclared” variable before accessing it.
In this quick guide, we’ll explore three methods to check if a variable is declared:
- Method #1: Using the
typeof
operator
- Method #1: Using the
- Method #2: Using
Object.prototype.hasOwnProperty()
- Method #2: Using
- Method #3: Using the
in
operator
- Method #3: Using the
- Bonus tip: Optional chaining
Let’s take a closer look at each method.
JavaScript isset with the typeof
operator
The typeof
operator takes an operand and returns the type of its value. The return value is always a string. So if the variable isn’t declared, typeof returns the string 'undefined'
.
typeof 12
// output: 'number'
typeof 'Hello!'
// output: 'string'
typeof NonExistantVariable
// output: 'undefined'
This is a safe method to test potentially undeclared variables before accessing them:
// if someVariable is declared ...
if (typeof someVariable !== 'undefined') {
// Do something with the variable ...
}
⚠️ Please note: If you try to access a block-scoped local variable or constant (declared by let
or const
), you'll get a ReferenceError (even when using typeof). This is due to a concept called the temporal dead zone (TDZ).
A variable is in the temporal dead zone from the beginning of its block until it's declared and intialized.
function myFunction() {
if (typeof someVariable !== 'undefined') {
// Do something here ...
}
// Declaring the variable after using typeof
let someVariable = 'someValue'
}
This rule doesn't apply to variables defined with var
, thanks to hoisting, where var
declarations are executed before any other code, no matter where defined.
Please note only the variable declaration is hoisted, but initialization (assignment of the value) happens until the code execution reaches the declaration line - until then, the variable remains undefined
.
So to test if a variable is declared and not null
:
if (typeof someVariable !== 'undefined' && someVariable != null) {
// Do something here ...
}
JavaScript isset with hasOwnProperty()
If you want to check for the existence of a property inside an object, you can use hasOwnProperty()
. This method returns true
if the specified property is a direct property of the object - even if the value is undefined
.
const artist = {
name: 'Jimi Hendrix',
instrument: 'Guitar'
}
console.log(artist.hasOwnProperty('name')) // output: true
console.log(artist.hasOwnProperty('instrumernt')) // output: true
console.log(artist.hasOwnProperty('genre')) // output: false
Object.prototype.hasOwnProperty()
returns false
if:
The property doesn't exist
Or has it been inherited
let artist = {
name: 'Jimi Hendrix'
}
console.log(artist.toString()) // [object Object]
console.log(artist.hasOwnProperty('toString')) // false
In the above example, we can call the toString()
method because it's inherits the Object's prototype. However, when we check for its existence with hasOwnProperty()
, we get false
as it isn't a direct method.
If you also want to check the value isn't nullish (just like PHP), you can do so like:
const artist = {
name: 'Jimi Hendrix',
instrument: 'Guitar',
genre: undefined,
albums: null
}
console.log(artist.hasOwnProperty('genre') && artist.genre != null)
// output: false
console.log(artist.hasOwnProperty('albums') && artist.genre != null)
// output: false
Please note the ==
operator does an equality check rather than an identity check like the ===
operator.
Since most JavaScript objects inherit the prototype of Object, you can call hasOwnProperty()
on arrays too:
// Checking if an array index exists:
const fruits = ['apple', 'orange', 'banana']
fruits.hasOwnProperty(3) // false
fruits.hasOwnProperty(2) // true
If you call hasOwnProperty()
on objects with a null prototype, you'll get a TypeError.
The static method Object.hasOwn()
has been introduced (since Chrome 93 and Firefox 92) as an alternative to hasOwnProperty()
. This method is recommended over hasOwnProperty()
because it also works with objects with a null prototype:
const artist = Object.create(null)
artist.instrument = 'Guitar'
console.log(Object.hasOwn(artist, 'instrument'))
// output: true
JavaScript isset with the in
operator
The in
operator checks if a property exists inside an object or its prototype chain. This is unlike the hasOwnProperty()
and Object.hasOwn()
methods that only consider the direct properties.
const artist = {
name: 'Jimi Hendrix',
instrument: 'Guitar',
}
console.log('name' in artist) // output: true
console.log('toString' in artist) // output: true
You can also test array indices with the in
operator:
const fruits = ['apple', 'orange', 'banana']
console.log(2 in fruits) // output: true
console.log(6 in fruits) // output: false
Making a custom JavaScript isset function with the in
operator should be easy:
const artist = {
name: 'Jimi Hendrix',
instrument: 'guitar',
genre: null,
albums: undefined
}
function isset(object, identifier) {
//Works for objects and arrays
if (typeof object !== 'object') {
throw new TypeError('The first argument is expected to be of type object')
}
return identifier in object && object[identifier] != null
}
console.log(isset(artist, 'name')) // output: true
console.log(isset(artist, 'instrument')) // output: true
console.log(isset(artist, 'genre')) // output: false
console.log(isset(artist, 'albums')) // output: false
Bonus tip: using optional chaining (?.
)
The ?.
operator works like the .
chaining operator with one difference: If a reference is nullish (null or undefined), the expression short-circuits with a return value of undefined
.
const obj = {
firstLevel: {
secondLevel: {
value: 'some value'
}
}
}
console.log(obj.firstLevel?.secondLevel?.thirdLevel?.value)
// output: undefined
console.log(obj.firstLevel?.secondLevel?.value)
// output: some value
If we did it without the optional chaining, we'd get a TypeError.
console.log(obj.firstLevel.secondLevel.thirdLevel.value)
// Uncaught TypeError: Cannot read properties of undefined (reading 'value')
The ?.
operator is a safe way of accessing nested properties when there's a possibility that a reference might be missing.
You can also use it with method calls; In that case, it'll return undefined
if the method doesn't exist:
let artist = {
name: 'Jimi Hendrix'
}
const result = artist.perform?.();
console.log(result)
If you want to do optional chaining with arrays, you can use them with the bracket notation:
const arr = [1, 2, 3, 4, 5]
console.log(arr?.[10]); // output: undefined
console.log(arr?.[2]); // output: 3
I think that does it! I hope you learned something new today.
Thanks for reading.
❤️ You might like: