Discussing the instantiation of classes in JavaScript

In my JavaScript class, I have a method called resetRule():

resetRule() {
  let sheetRules = Array.from(this.sheet.rules);
  sheetRules.forEach(function(node, i) {
    if(node.name != undefined) {
      newRule.sheet.deleteRule(i);
    }
  });
}

When you create an instance of a class, you need to assign it to a variable like this:

const newRule = new NewRule(*params*);

The methods and properties of the class can refer to the object using this. For example:

this.method();
this.property;

My question is: How can we reference the variable that instantiated the class within a function called by one of its methods?

In other words, when a function inside a class method changes the scope and alters the definition of this, how can we access the original variable that created the instance of the class when outside the scope of the class methods?


While working on this question, I discovered a way to set the this value for a .forEach loop like so:

resetRule() {
  let sheetRules = Array.from(this.sheet.rules);
  sheetRules.forEach(function(node, i) {
    if(node.name != undefined) {
      this.sheet.deleteRule(i);
    }
  }, this);
}

However, I'm aware that this solution relies on the capabilities of the .forEach method. I still seek a general approach to handle such situations.

Answer ā„–1

Here is a solution that may assist you with your problem, based on the example provided.

class Rule {
  constructor(rules) {
    this.sheet = {
      rules: rules || []
    }
  }
  
  log(){
    console.log('rules:',this.sheet.rules)
  }
  
  resetRule() {
    let sheetRules = Array.from(this.sheet.rules);
    let self = this;       // <-- capturing the instance here
    
    sheetRules.forEach(function(node, i) {
      self.log()           // <-- using 'self' in forEach   
      if (node.name != undefined)
        this.sheet.deleteRule(i);
    });
  }
}
const fooRule = new Rule(['foo'])
const barRule = new Rule(['bar'])

fooRule.resetRule()
barRule.resetRule()

fooRule.log()
barRule.log()

Your forEach implementation works because you passed this as an argument for the thisArg parameter. However, alternatively, you could have defined it as a variable in the outer scope and utilized it within the block scope.

Creating a variable like self or that and assigning it to this can be beneficial, particularly for arrow functions where this points to the enclosing scope instead of the instance object.

Answer ā„–2

One approach is to create a temporary variable named self, or any other name you prefer, which allows you to access both the object containing the current instance and the anonymous function passed to forEach. In this case, this refers to sheetRules if another variable is not specified for this.

resetRule() {
  let sheetRules = Array.from(this.sheet.rules);
  let self = this;
  sheetRules.forEach(function(node, i) {
    if(node.name != undefined) {
      self.sheet.deleteRule(i);
    }
  });
}

Answer ā„–3

It seems like you're interested in maintaining the scope of your code. Luckily, there are several approaches you can take.

One option is to utilize Function.prototype.bind() or Function.prototype.call() to explicitly define the context of this when calling these functions.

Another approach would be to ensure that the scope of this is accessible where needed:

var MyClass = function () {
    var vm = this; // Storing the local scope in a variable for clarity and consistency.

    vm.methodA = function () {
        var vm = this; // Continually updating our 'vm' pointer for context.

        globalMethod.then(function () {
            // By referencing the 'vm' variable, we can maintain the context of `this`.
            vm.methodB();
        });
    };

    vm.methodB = function () {
        console.log('I accomplished something!');
    };
};

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

Prevent scaling in CSS3DRenderer

For a detailed explanation of what I am attempting to achieve, please refer to my previous question here. In summary: My goal is to have HTML elements rotate in sync with OrbitControls to give the illusion that these elements are attached to a globe and m ...

Is it possible in HTML to create an "intelligent" overflow effect where text is truncated and replaced with an ellipsis "..." followed by a link to view the full content?

I have a <div> that has a limited size, and I am looking for a way to display multiline text in it. If the text exceeds the available space, I would like to add "..." at the end along with a link to view the full content on another page. Is there a ...

Separate and add on the change validity status of an AngularJS form

If you want to test it out, check this jsFiddle link: HERE (it's recommended to view on a new jsFiddle, refer to the EDIT section of this post) I've noticed what seems like a bug in AngularJS or at least an unexpected behavior. When I detach a f ...

The upcoming development does not involve creating an entire HTML webpage using on-demand static site generation (SS

Iā€™m encountering a problem when utilizing getStaticPaths and getStaticProps to create an on-demand SSG for a sharing page. My setup involves Next v12.1.0 and React 17.0.2. After building a specific /[id] page, I can retrieve the data but the HTML output ...

Ways to conceal numerous objects

I need to create a function where I can hide multiple elements by pressing a button based on the value of checkboxes. If a checkbox is checked, the corresponding element should be hidden. Currently, I have some code that only works for the first element: ...

Developing a website with all features and functionality using only traditional coding techniques

When I mention "Vanilla Coding", I mean websites that rely solely on HTML, JavaScript, and CSS without any server side coding like PHP or ASP. I've noticed there are many websites out there that seem to function perfectly fine without using common se ...

How to style large numbers with AngularJS

I'm facing a challenge with large numbers in a table and I'm seeking a solution to format them, ideally as $13b, $10m... Has anyone encountered this issue before and discovered a customized filter or solution for it? Appreciate any help! ...

Creating materials in Three.js from Blender source files

After exporting a simple white material with my geometry from Blender, I noticed that the Three.js loader somehow created a MeshPhongMaterial "type" object from the source JSON file: ... "materials":[{ "colorEmissive":[0,0,0], "c ...

Tips for creating a Google Chart using temperature and humidity data sourced from an XML file

Below is the XML file I am working with: <data> <temp>21</temp> <humidity>17</humidity> <analog>670</analog> <analog>908</analog> <analog>628</analog> <analog>909</analog> <L ...

What could be the reason behind an Ajax Auto-Complete feature suddenly malfunctioning when moving to a new page within the same website?

Working on a website featuring an auto-complete search box powered by Ajax, Javascript, and PHP. As the user types into the search box, an ajax request triggers a php file to query a database and return possible results. Everything works smoothly until the ...

Tips on utilizing the Google Maps autocomplete feature exclusively for place suggestions, without displaying the map itself

I have implemented an input form where users can see suggestions of places related to the word they type. I came across a solution using Google Maps autocomplete, but I do not need the map itself. All I require is the functionality that provides suggestion ...

Angular UI Bootstrap collapse directive fails to trigger expandDone() function

I am currently utilizing UI Bootstrap for Angular in one of my projects, and I have developed a directive that encapsulates the collapse functionality from UI Bootstrap. Here is how it looks: app.directive( 'arSection', ['$timeout', fu ...

Changing the color of options in a list when clicked: a step-by-step guide

Here is the HTML code I have: <li onclick="switchColors()"> <a class="x" href="Faculty.php">Faculty</a> </li> <li onclick="switchColors()"> <a class="x" href="Contact.php">Contact</a> </li> And here ...

Tips for arranging alternating elements in a column layout using an array data model

In the $scope there is a dynamic array and in the HTML template, there are three columns. The goal is to render elements from the array in the HTML like this: <div class="first-column"> <div><!--element of (index + 3) % 3 === 0 will be pl ...

The retrieval of data using PHP, MYSQL, and AJAX is unsuccessful

A dropdown menu contains the names of months, represented by numbers from 1 to 12: When a month is selected, I want to retrieve data from a database to display relevant tournaments for that specific month. The SQL code has been tested and confirmed to be ...

Unexpected values being captured by Request.Form from Dynamic Textboxes

I am currently working with dynamic text boxes and retrieving their values in the code behind file. These text boxes are created using Javascript on my ASP.NET page. Here is a snippet of my code: <script type="text/javascript"> $(docume ...

Is it possible to run an existing NextJS app with API routes on a mobile platform using either Capacitor or Expo?

I have an established NextJS application that heavily relies on Next's API routes. My goal is to transition the current codebase to function in a mobile environment. I've experimented with Capacitor and attempted to export it as a static site, bu ...

Angular Position Animation with PhysicsJS

A juggling game is being created using PhysicsJS. The game consists of a ball in the shape of a circle and a shoe in the shape of a square using a convex-polygon. The shoe remains fixed and moves along the x-axis when the mouse is moved. The square shoe: ...

Failure to validate two dates, even when they are both in date format within AngularJS

Although it may seem silly to ask, I am confused as to why this is not working. Even though all the values appear fine in debug mode. My goal is to display an error if the productionStartFrom date is before the current date. Controller scope.currentDate ...

Updating deeply nested document in Mongoose

Is it possible to change the value of array1.array2.status, according to the schema provided below? const SomeSchema = new mongoose.Schema({ status: Boolean, array1: [{ array2[{ status: boolean }] }] }) ...