Shadowing Properties in JavaScript

Pallavi Ganpat Babar
Nerd For Tech
Published in
4 min readAug 5, 2023

--

When working with JavaScript, developers come across a variety of language features that can result in unexpected behaviour. One example is “Shadowing Properties.” When a local variable within a function or block has the same name as a variable in another scope, this is known as shadowing. This phenomenon can lead to confusion and bugs if not understood correctly.

If you relate to the third person. You are at the right place. After reading this article, you will completely understand it.

Variable scope in JavaScript is divided into two types: global scope and local scope. Global variables are those declared outside of any function or block, whereas local variables are those declared within a function or block. When a variable is shadowed, the variable in the local scope takes precedence over the variable in the outer scope. That is, any references to that variable within the local scope will refer to the local variable rather than the outer one.

Let’s look at some examples of shadowing properties:

let outerVar = "I am in the outer scope";

function outerFunction() {
let outerVar = "I am in the scope of outerFunction.";
console.log(outerVar); // Output: "I am in the scope of outerFunction."

function innerFunction() {
let innerVar = "I am in the scope of innerFunction.";
console.log(innerVar); // Output: "I am in the scope of innerFunction."
console.log(outerVar); // Output: "I am in the scope of outerFunction."
}

innerFunction();
}

console.log(outerVar); // Output: "I am in the outer scope"
outerFunction();

In this example, we have a variable named outerVar declared in the global scope. Inside the outerFunction(), we have another variable with the same name outerVar, which shadows the outer scope's outerVar. Then, we have an innerFunction() declared inside outerFunction(), and it has its own variable named innerVar.

When we call outerFunction(), it first prints the value of the outerVar from the outer function, which is "I am from the outer function". Inside innerFunction(), we print the value of innerVar, which is "I am from the inner function", and also outerVar, which still refers to the variable in the outer function's scope since it is the nearest one in the hierarchy.

Finally, when we print outerVar again outside the function calls, it refers to the outerVar in the global scope, and the output is "I am from the outer scope".

This example demonstrates how variables are shadowed in nested scopes, and the variable’s value is determined by the scope in which it is defined.

Can a prototype’s defined properties be shadowed?

Yes, In JavaScript, it is possible to shadow properties defined within a prototype. When an object is created with a constructor function and the prototype property is used to add properties or methods to the constructor’s prototype, those properties are made available to all instances created by that constructor. However, these properties can be shadowed in individual instances.

Let us use an example to demonstrate this:

const person = {
name: "Naina",
age: 24,
hasOwnProperty: "I'm shadowing hasOwnProperty!"
};

console.log(person.name); // Output: "Naina"
console.log(person.age); // Output: 24

// Attempting to use hasOwnProperty method on the person object
console.log(person.hasOwnProperty("name")); // Output: TypeError: person.hasOwnProperty is not a function

// Accessing the shadowed property
console.log(person.hasOwnProperty); // Output: "I'm shadowing hasOwnProperty!"

In this example, we have a person object with the properties name and age. We’ve also added a property to the object called hasOwnProperty which has a string value. By doing so, we are shadowing JavaScript’s built-in hasOwnProperty method.

When we try to use the hasOwnProperty on the person object with person.hasOwnProperty("name") throws a TypeError because the property hasOwnProperty within the object is no longer a function but a string.

However, we can still use person.hasOwnProperty to directly access the shadowed property. The string value “I’m shadowing hasOwnProperty!” will be returned in this case.

Will I be able to use the original hasOwnProperty again?

You certainly can. Even if an object’s hasOwnProperty method is shadowed, you can still use the Object.hasOwnProperty.call() method to determine whether a key exists in the object. This method avoids the shadowed hasOwnProperty property and allows you to access the original method from the Object prototype.

Here’s how you can use Object.hasOwnProperty.call():

const person = {
name: "Naina",
age: 24,
hasOwnProperty: "I'm shadowing hasOwnProperty!"
};

// Using Object.hasOwnProperty.call() to check if the key exists in the object
console.log(Object.hasOwnProperty.call(person, "name")); // Output: true
console.log(Object.hasOwnProperty.call(person, "age")); // Output: true
console.log(Object.hasOwnProperty.call(person, "gender")); // Output: false

In this example, we use Object.hasOwnProperty.call() to check if specific keys ("name", "age", and "gender") exist in the person object. The Object.hasOwnProperty.call() method works by calling the original hasOwnProperty method from the Object prototype, rather than using the shadowed version within the person object.

By using Object.hasOwnProperty.call(), you can avoid potential issues caused by shadowing and safely check for the existence of keys in an object, regardless of any property shadowing that might have occurred. This technique ensures that you are using the intended built-in method and that your code behaves consistently.

In Conclusion, Shadowing properties in JavaScript can lead to mysteries and surprises. When it comes to variables or object properties, the inner scope always takes centre stage, hiding the outer ones. While shadowing has its uses, it must be used with caution to avoid unintended consequences. Keep naming, scoping, and the powerful Object in mind.Use the hasOwnProperty.call() trick to tame shadows and write bug-free code!

--

--

Pallavi Ganpat Babar
Nerd For Tech

Pallavi is a software developer and writer, passionate about exploring the latest tech trends. Follow for insights on software development, tech and more.