Is it possible to retrieve a class's array of properties without creating an instance of it?

It appears that there might be a way to accomplish this task by dynamically constructing a form based on a class definition (Angular) without being dependent on the specific class itself. This approach would allow for scalability, enabling the addition of fields to the class without needing to update the form logic and template.

Is there a method or possibly an NPM package available to achieve this?

I have come across using ClassName.toString(), but parsing it could prove difficult. If necessary, I may consider developing a module to handle this task.

The idea of creating a dummy instance of the class solely for property enumeration purposes seems like a less efficient route to take.

Answer №1

If you're looking to retrieve all the properties of an object in JavaScript, one way to do so is by using the method Object.getOwnPropertyNames().

Consider the following example class:

class Foo {
  setBar() {
    throw Error('not implemented');
    return false;
  }
  getBar() {
    throw Error('not implemented');
    return false;
  }
}

To get a list of the properties defined on the prototype of this class, you can use:

Object.getOwnPropertyNames(Foo.prototype)

This will result in an array containing:

["constructor", "setBar", "getBar"]

In my research, I initially explored using Object.keys() as an alternative. While it didn't provide the desired outcome, you may find the documentation for the polyfill for Object.keys() helpful. It includes code for filtering out certain default properties like constructor and toString, and also correctly implements hasOwnProperty.

For more insights on listing down all prototype properties of a JavaScript object, you can refer to Bergi's answer on this thread.

Answer №2

Is there another approach? You can define your class as a function and assign properties to its prototype:

var Monarchs = function() {
};

Monarchs.prototype = {
  "henry" : "viii",
  "elizabeth" : "i"
}

console.log(Object.keys(Monarchs.prototype))

// Output will be
// [ 'henry', 'elizabeth' ]

Answer №3

Accessing the properties of a class prototype without instantiation may result in only methods and accessor descriptors being exposed - data properties remain undisclosed until actual instantiation due to the potential influence constructor arguments can have on the properties' types, values, and quantities. Instances may not be desired for various reasons, such as tracking static counters; hence, a possible solution is to create a "shadow" duplicate of the class dynamically and instantiate it with sample constructor arguments.</p>
<p><div>
<div>
<pre class="lang-js"><code>    /**
     * Obtain properties from a class definition without creating instances
     *
     * @param cls: class
     * @param args: example arguments to provide to the shadow constructor
     * @usage `const props = getInstanceProperties(MyClass);`
     * @notice this will regex replace the classname (potential issue with strings containing that substring)
     */
    const getInstanceProperties = (cls, args = [], ignore = ['constructor', 'toString']) => {
        const className = cls.prototype.constructor.name;
        const shadowCode = cls.toString().replace(new RegExp(`${className}`, 'g'), `_${className}_`);
        const shadowClass = eval(`(${shadowCode})`);
        const o = new shadowClass(...args);
        const methodsAndAccessors = Object.getOwnPropertyDescriptors(cls.prototype);
        const dataDescriptors = Object.getOwnPropertyDescriptors(o);
        const descriptors = Object.assign({}, methodsAndAccessors, dataDescriptors);
        ignore.forEach(name => delete descriptors[name]);
        return descriptors;
    };


    class Foo extends Object {
      static instances = 0;
      #myPrivateVar = 123;
      myValue=123;
      constructor(){
          super();
          this.myConstructorProp = ++Foo.instances;
      }
      myMethod() {}
      set myAccessor(x){}
    }

    console.log(Object.keys(getInstanceProperties(Foo)));

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

Increase the identification of HTML element with jQuery

I've encountered an issue while trying to increment the id of 2 HTML elements, hwAddition and itemNumber, upon a button click event. The HTML code in question is as follows: <div id="hwAddition"> <div id="itemNumber" s ...

Improving form handling with Vuex: Ensuring state is only updated after pressing the submit button

I am currently working on developing a form that pulls data from a Vuex store, allowing users to update the form fields and then submit when they are ready. Most tutorials I have seen use v-model with computed get() and set() to retrieve values from the s ...

Trouble with AngularJS Smart Table when dealing with live data streams

Currently, I am facing a scenario where I am utilizing angularJs smart table for filtering. Here is the HTML code: <section class="main" ng-init="listAllWorkOrderData()"> <table st-table="listWorkOrderResponse"> <thead> ...

Sometimes the AngularJS scope is refreshed only intermittently

I am encountering an issue with a list of cards retrieved from an API and displayed in a table using ng-repeat. The problem arises when I attempt to delete a card - sometimes it remains in the view, while other times it disappears as expected after confirm ...

The reason why the script and div tags are so common in HTML is because they serve different purposes. However, it's

Hey there, friend! I've searched on baidu.com, cnds, and stack overflow, but couldn't find an answer. I have two questions: "why can script and div tags be used so much in HTML?" and "why is there only one html and body tag in HTML?" For example: ...

Discrepancy in functionality between .show() and .append() methods within JQuery

I have a container with an ID of "poidiv" that is hidden (display: none) initially. My goal is to dynamically load this container multiple times using a loop, where the maximum value for the loop is not predetermined. I attempted to achieve this using jQue ...

Maintain the dropdown selection while the table is being updated

My table updates every few seconds and each row has a dropdown menu that allows users to take actions on that row. However, the problem is that when new data is received from the database, the dropdown menu closes if it was open. This can be frustrating f ...

Integrating redux-form with the react-widgets DateTimePicker component

I am currently working on a project using ReactJS with Redux and I am trying to incorporate a form similar to the one shown in this example: Most of the components are working well, but I am encountering an issue with the DateTimePicker due to the momentL ...

Client-sessions in ExpressJS fail to persist session data

I recently integrated the client-sessions module into my Express backend. After setting it up as follows: var sessions = require('client-sessions'); app.use(sessions({ cookieName: Constants.CLIENT_SESSION_NAME, // pi_client_session ...

Timeout error for WebSocket connection on JavaScript client

My first attempt at using websockets is not going as planned. Since my IP address changes frequently, I decided to make the following websocket call on the server-side: $echo = new echoServer("myurl.com","9000"); On the client-side, I'm making the f ...

Receiving accolades within a nested function while implementing a Higher Order Component

I'm currently working on creating a Higher Order Component (HOC) to manage some functionalities in React. Here is my implementation: import React, { useState } from "react"; export default function withFormControl(WrappedComponent) { return props ...

Searching and replacing query strings in a URL using JQuery according to the chosen option in an HTML dropdown menu

Is there a way to use jQuery to dynamically change a specific value in the query string by finding and replacing that value based on the selection made from a dropdown menu on the webpage? For example: Imagine we have this query string on the current page ...

Tips for managing an interval for play, pause, and stop functions in JavaScript or Node.js

In my main file, I have an API to control the playback of a video. main.js const { mainModule } = require('process'); const { startVideo, pauseVideo, stopVideo } = require('./modules/video.js'); function init(payload) { if(payl ...

how to choose the :after pseudo-element with jQuery

Below are the codes I have tried. When this popup appears, I want to be able to close the entire popbox using the close button. CSS code .bigdiv{ display:none; background-color:#efefef; box-shadow: 10px 10px 10px 100000px rgba(0, 0, 0, 0.4); ...

Employ the $scope.go() method within a function written in JavaScript

I am working with some HTML code that looks like this <body ng-app="app" ng-controller="IndexCtrl" id="indexBody"> <h1>test</h1> </body> Next, in a JavaScript function, I retrieve the scope like so function myFx() { ...

What is the best way to bring the global stylesheet into a Vue component?

Embarking on my first VueJS project, I decided to create a global stylesheet to maintain consistent styles across different components. After installing the SCSS loader and setting up my stylesheets, I encountered an issue. $mainFont: 'PoppinsRegular, ...

Transferring and displaying messages between PHP scripts

On my page (index.php), I have a simple layout consisting of two DIVs. The left side (#leftDIV) contains a form and another DIV (#messages) for displaying error messages. On the right side, there is another DIV (#mapAJAX) which houses a PHP script responsi ...

Is the current version of NPM React-router too cutting-edge for your needs

When I use the command npm -v react-router on my React app, it shows version 6.9.0. However, when I check the npmjs page for react-router, the latest version available is 5.0.1. How can this discrepancy be explained? ...

Tips for resolving issues with storing data in a text box that is constantly being added to

Can someone please assist me with this issue I'm facing? I am using isset to check if the index is defined, but it stores 0 instead of saving the value of the textbox. How should I tackle this problem? If I don't check if the index is defined and ...

Tips for repairing a button using a JavaScript function in an HTML document

I am currently working on extracting titles from body text. To achieve this, I have created a button and linked my function to it. The issue I am facing is that when I click on the button, it disappears from its original position. I intend to keep it in pl ...