Ways to guarantee a distinct identifier for every object that derives from a prototype in JavaScript

My JavaScript constructor looks like this:

var BaseThing = function() {
  this.id = generateGuid();
}

When a new BaseThing is created, the ID is unique each time.

var thingOne = new BaseThing();
var thingTwo = new BaseThing();
console.log(thingOne.id === thingTwo.id); // false

However, things become complicated when I attempt to create objects that inherit from BaseThing:

var FancyThing = function() {
   this.fanciness = "considerable";
}
FancyThing.prototype = new BaseThing();

var thingOne = new FancyThing();
var thingTwo = new FancyThing();
console.log(thingOne.id === thingTwo.id); // true

This behavior is expected due to prototypical inheritance, but it's not what I desire; I want the ID to be unique without needing to re-implement it in each inheriting object.

What would be the most effective approach to achieve this? My own ideas were either (a) reimplementing the id in every child constructor (which seems counterintuitive to inheritance) or (b) incorporating an initialize function into BaseThing (but I don't want to worry about ensuring it's called every time a Thing is created).

Answer №1

One issue arises when your child does not inherit the constructor from the parent function. To address this, you can first invoke the parent function to achieve the desired outcome without rewriting everything within the parent function. This can be accomplished using the .apply method.

var counter = 0;
function generateGuid() { return ++counter; }

var BaseThing = function() {
  this.id = generateGuid();
}

var thingOne = new BaseThing();
var thingTwo = new BaseThing();
console.log(thingOne.id === thingTwo.id); // false


var FancyThing = function() {
  BaseThing.apply(this, arguments) // inherit
  this.fanciness = "considerable";
}
FancyThing.prototype = Object.create(BaseThing.prototype, {constructor: {value: FancyThing, writable: true, configurable: true}});

var thingOne = new FancyThing();
var thingTwo = new FancyThing();
console.log(thingOne.id === thingTwo.id); // false

Regrettably, I am unaware of a method to extend from a parent without indicating somehow that the parent is being referred to.

Answer №2

If you want to add a touch of elegance, consider relocating the id property to BaseThing.prototype and making it a "computed" property using Object.defineProperty

var BaseThing = function() {
  //will define id on prototype
  //this.id = generateGuid();
}

Object.defineProperty(BaseThing.prototype, 'id', {
  configurable: true,
  enumerable: true,
  get: function() {
    //redefine property on first call
    Object.defineProperty(this, 'id', {
        configurable: false,
        enumerable: true,
        value: generateGuid()
    })

    return this.id
  }
})

Check out the demo here.

Answer №3

Sure, one way to approach this is by using the call method along with apply in JavaScript. Here's an example:

function generateId(){
    return Math.random(); 
}

var BaseObject = function() {
  this.id = generateId();
}

var AdvancedObject = function() {
   BaseObject.call(this);
   this.advancementLevel = "high";
}

var obj = new AdvancedObject();
console.log(obj);

https://example.com/code-example

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

Creating a JSON object from an array of data using TypeScript

This might not be the most popular question, but I'm asking for educational purposes... Here is my current setup: data = {COLUMN1: "DATA1", COLUMN2: "DATA2", COLUMN3: "DATA3", ..., COLUMNn: "DATAn"}; keyColumns = ["COLUMN2", "COLUMN5", "COLUMN9"]; ...

Having trouble fetching information from a JSON file stored in a local directory while using Angular 7

I am currently experiencing an issue with my code. It works fine when fetching data from a URL, but when I try to read from a local JSON file located in the assets folder, it returns an error. searchData() { const url: any = 'https://jsonplaceholde ...

What is the reason for triggering a rerender when there is a modification to a map() element using document.querySelector() in JS/next.js?

const slides = [ [string1, string2, stringi], [string1, string2, stringi], [string1, string2, stringi], [string1, string2, stringi], ]; const changeSlide = (num) => { const discipline = document.querySelector("#changeSlide-&quo ...

Well, it appears that I am having trouble establishing a connection between the users in this chatting application

I'm encountering a problem with establishing a connection between two users. I have already installed express and socket.io, but for some reason, the message is not getting through to the receiver's end. The code seems to be running fine as I can ...

What could be causing such a significant variance in performance for a wrapped JavaScript function?

Here is a code snippet that I have been experimenting with: function Run () { var n = 2*1e7; var inside = 0; while (n--) { if (Math.pow(Math.random(), 2) + Math.pow(Math.random(), 2) < 1) inside++; } return inside; } var s ...

The reason why Express is not directing to the static React build files is due to the absence of a specific URL slug

The Scenario Currently, I'm in the process of developing a React application that is being served statically through Express. To clarify, the React app is constructed using npm run build and the resulting static files are stored within the build/ ...

Properly aligning text with checkboxes using HTML/CSS and tags like <span> or <div>

My goal is to have the text displayed as a block in alignment with the checkbox, adjusting based on the sidebar's width. For reference: Current Layout Preferred Layout I have shared the code on CodePen (taking into account screen resolution and wi ...

Leverage multiple services within a single AngularJS controller

Is it possible to use multiple services in the same controller? Currently, I am able to achieve this with different services, but it seems to only perform one service. <!DOCTYPE html> <html> <script src="http://ajax.googleapis.com/ajax/libs ...

"Is it possible to move the text on the canvas by dragging it to where you want it to be

Seeking help again after an unsuccessful attempt. How can I allow the user to add text to the canvas by dragging it to their desired location? For example, if they input text somewhere, it should appear on the canvas and then be draggable to any position ...

Error encountered in Express middleware: Attempting to write private member #nextId to an object that was not declared in its class

Currently, I am in the process of developing a custom logger for my express JS application and encountering an issue. The error message TypeError: Cannot write private member #nextId to an object whose class did not declare it is appearing within my middle ...

"Use jQuery to toggle the slide effect for the first element of a

Below is the HTML code snippet: <div class="row header collapse"> Content 1 <i class="fas fa-chevron-circle-up" ></i> </div> <div class="instructions-container"> <div></di ...

Eliminating 'related' elements with jQuery

I am facing an issue with deleting items in a list. The list contains two types of products, product-x and product-y. Whenever I delete one type of product, I want the equivalent product of the other type to also be deleted. I have tried different approac ...

Add a click event to elements that match

I must admit that I am not particularly knowledgeable in Javascript/jQuery and my question might come across as trivial. However, I am trying to assign a click event to every element on the page with the following code: $(document).ready(function () { ...

Navigating from a web address to making an asynchronous request using history.js

As I work on a small website that features multiple pages with similar layouts, I often find that only the content within a specific div varies. The rest of the elements such as navigation and header remain consistent throughout. To address this, I have s ...

Can anyone help me troubleshoot this issue with uploading external JS scripts into my HTML code?

I'm currently facing an issue with my HTML document where the external js file is not loading. Here's a snippet of the HTML: <!DOCTYPE html> <html> <head> <title>...</title> <meta name="viewport" conten ...

Include characteristics in JSX.Element following its declaration

Suppose I have an item in a dictionary with the following structure: let item = { element: <myElement/>, color: "#0e76a8" } Is it possible to add a style attribute to the item.element within the render() method? I tried the following appro ...

Best practices for updating the value of a specific key within an object that contains recursion in JavaScript/TypeScript

I have a tree component that uses the following data structure type TreeNode = { id: string, parentId: string, renderer: () => React.ReactNode, expanded: boolean, children?: Array<TreeNode>, } Now, I am looking to add functionality for ...

Is there a way to access hover effect information in Atom editor similar to how it appears in VScode?

Is there a specific plugin required in Atom to display information when hovering over variables, objects, or functions similar to intellisense? VSCode does this automatically, but I am looking for the same functionality in Atom. https://i.stack.imgur.com/ ...

Setting the value of a custom component property dynamically after the component has been rendered

I'm currently developing an Angular application and have a specific requirement to work on. I am using a custom component with 3 inputs, and I want to bind this custom component tag in the HTML of my page. <my-column [setInfo]="info" [dis ...

Adding items to the array is only effective when done within the loop

My approach involves retrieving data from an API using axios, organizing it within a function named "RefractorData()," and then pushing it onto an existing array. However, I have encountered a problem where the array gets populated within a forEach loop, a ...