In JavaScript, what causes a reference error when reading an undeclared variable, but returns undefined when accessing an undeclared object property

When I run the code below and print this.property2 in the console, the JS engine returns undefined. However, if I simply print property2 instead, the compiler throws a reference error. In order to avoid this error, I need to declare the variable property2, but even then the return value is undefined.

function foo() {
  var property;
  console.log(this.property2)
  console.log(this.property2 === property2)
  console.log(property2)
}

foo.property="property value";
var property2; // adjusted to fix reference error
foo();
console.log(foo.property);

The code shows that this.property2 equals property2, so why does JavaScript handle them differently?

Here's my question: are both variables (this.property2 and property2) distinct from each other? If they are, then why does the comparison yield true? And if not, why do I have to explicitly declare property2 to fetch its value while this.property2 retrieves values without any prior declaration?

Could there be something crucial that I'm overlooking here?

Answer №1

Why does reading an undeclared variable result in a reference error, while accessing an undeclared object property returns undefined in JavaScript?

The reason for this difference ultimately boils down to the decision made by Brendan Eich during the design phase. However, we can speculate on some possible rationale behind his choices:

In the first scenario, when dealing with an unknown identifier, there is no context available. In contrast, when trying to access an object property, there exists some context that informs us we are searching within an object. Furthermore, it's worth noting that assigning a value to an unknown property does not throw an error - instead, it creates the property. This aligns well with the ability to read an unknown property without encountering an error.

Eich could have opted to make reading from an unknown object property trigger an error, but he chose not to do so and that decision remains unchanged today.

It's interesting to mention that initially, assigning a value to an unknown identifier served as a means of creating a global variable. Fortunately, this behavior was corrected with the introduction of strict mode.


As a side note: Properties are not declared; they are created. The act of declaration applies to functions, classes (which essentially function as functions), and variables only.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is there a way to include the request body (req.body) in the msg object using express-winston?

My current challenge involves logging {{ req.body }} using the msg: object in express-winston. Even after whitelisting the body with expressWinston.requestWhitelist.push('body');, it still does not appear in the log. export const accessLogger = ...

Start Vue.js development server with SSL enabled (for secure HTTPS serving)

Issue with Development Environment: Recently, I encountered an obstacle related to enforcing HTTPS on external hosts as explained in "Deprecating Powerful Features on Insecure Origins". This problem arose because I have my development setup on my laptop an ...

Prevent Bootstrap dropdown menu from closing when clicked on

Is there a way to keep the dropdown menu class in Bootstrap open after clicking a link inside it? I need users to be able to choose a class from "type-of-visitors" and select an option in the dropdown menu without it closing. The "Go" button should be th ...

Defining the active element in the menu using JavaScript

I need help with my navigation menu: <ul> <li id="active"><a href="/">Home</a></li> <li><a href="/about/">About Us</a></li> <li><a href="/services/">Our Services</a>< ...

Add the item and increase its value within an array using AngularJS

http://plnkr.co/edit/NDTgTaTO1xT7bLS1FALN?p=preview <button ng-click="addRow()">add row</button> <div ng-repeat="row in rows"> <input type="text" placeholder="name"><input type="tel" placeholder="tel"> </div> I am cur ...

Resolve resources in Angular UI Router without triggering a page reload

Currently, I have implemented the following code to handle resource resolution when the main state is loaded. However, I am looking for a way to re-resolve the resource without having to reload the page. Reloading the page would negatively impact the user ...

What is the process for deleting keys and values from a JSON object?

I am currently working with the Spring Framework and AngularJS in JavaScript. I have successfully made an AJAX request, but encountered an issue when trying to remove certain keys and values from the response data. Here is my code: $.ajax({ type: &apo ...

Executing Sequential Jquery Functions in ASP.Net

I have successfully implemented two JQuery functions for Gridview in ASP.Net 1. Enhancing Gridview Header and Enabling Auto Scrollbars <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script& ...

The Event of XMLHttpRequest State Transition Error

Can anyone provide assistance in troubleshooting why the code below is not functioning as expected, displaying "something negative happened" instead of the desired PHP echo alert? The JavaScript code I am using is: window.onload = function(){ var re ...

Ensure that the placeholder remains visible as you type in the input field

Is there a way to implement an input text field in React with the placeholder "DD-MM-YYYY," that partially disappears as I start typing? For example, when I type "02-," only "-MM-YYYY" should remain visible as part of the placeholder. ...

"Utilizing jQuery to create a seamless loop with easing effects and the

I've been working on some code where I want elements to appear one by one with a delay of 700ms. Currently, all the elements are showing up at once. I've tried using setInterval and setTimeout functions but haven't had any success. If any ...

gulp-open not functioning properly following the use of createWriteStream

I am utilizing gulp, gulp-eslint, and gulp-open to generate a report detailing ESLint outcomes. The linting and file creation processes function correctly; however, the task aimed at opening the file containing my report encounters issues. gulp.task(&apos ...

Creating a New Form Dynamically and Using Ajax to Submit it

I am currently working on creating a form object in my code and populating it with data from input elements on the page. Instead of submitting an existing form via ajax, I want this submit action to extract information from 4 specific fields within the for ...

What is the best way to prevent duplicates in a Material-UI dropzone area?

Currently, I am utilizing the Material-UI Dropzone component from https://yuvaleros.github.io/material-ui-dropzone/ and my goal is to prevent users from uploading duplicate files that have been previously uploaded. I attempted using an onchange function t ...

Unable to retrieve Object property using computed method in Vue 3 vuex results in undefined value

When attempting to display the values of a computed property in the template using the syntax {{todo[0]['title']}}, I am receiving an 'undefined' output. However, using {{todo[0]]}} allows me to render the entire object. My goal is to b ...

multer is capable of utilizing [req.file.filename], however it is necessary to utilize either [req.files[0].filename] or [req.files.find({fieldname:"samplefield"})] within the code

When I upload my files using multer_upload.single('sample_fieldname'), retrieving the data is straightforward with req.file.*. However, how can I access this same data when utilizing multer with multiple files? For example, with multer_upload.fie ...

Exploring the power of nested loops within an AJAX call in Angular

I have been attempting to iterate through a variable, search for IDs, and then make an ajax call to retrieve the detailed content of the different IDs. In the Success function, I am trying to loop through the received content and extract the emails. While ...

Tips for adding/removing items in arrays using Ember.js

Is it possible to modify an array within an Ember object using methods like push and pop while still keeping the UI bindings updated? While I can easily display the contents of an array in an Ember object using Handlebars, making changes directly to the ...

Is there a way to prevent Chrome from highlighting text that matches the content of a `position: fixed` element?

I currently have a Toc element in my HTML with the property position: fixed. (This means it remains in place as you scroll) My goal is to prevent Chrome's Find Text feature from recognizing text within that Toc element. (Ideally using JavaScript) ...

javascript: unable to modify currentTime in <audio> tag

Struggling to create a progress bar for my HTML5 audioplayer and implement a function to change the playing track's time by tapping. I opted to use input[range], but encountering an issue where the current play time does not update when tapping on the ...