Which is more memory efficient: creating an object with functions defined on it using a function, or creating an instance of a class?

Imagine if I were to create a hypothetical class (this is purely for demonstration purposes)

class X {
  constructor(word, number) {
    this.wordNumberString = word + number;
  }
  saySomething() {
    return `${this.wordNumberString} ${this.wordNumberString}`;
  }
  addAnotherWordNumberString(word, number) {
    this.wordNumberString += word + number;
  }
}

Would developing a function that forms a closure, encapsulating data by defining functions within and returning them:

const generateX = (word, number) => {
  let wordNumberString = word + number;
  const saySomething = () => {
    return `${wordNumberString} ${wordNumberString}`;
  }
  const addAnotherWordNumberString = (word, number) => {
    wordNumberString += word + number;
  }
  return { saySomething, addAnotherWordNumberString };
}

be more efficient in terms of memory usage?

For instance, would

Array(100000).fill(null).map((_, i) => new X(i, new Date() + i*123456))

have greater benefits than:

Array(100000).fill(null).map((_, i) => generateX(i, new Date() + i*123456))

Answer №1

Let's discuss different approaches to programming in JavaScript: using a style with createA or similar is common, while using class A or similar is also popular.

Would [creating different functions each time] be less efficient in terms of memory?

Yes, it would be slightly less efficient due to function objects and closure, but whether this impact is significant depends on other factors as well.

When using the class, function objects for methods are reused by each instance of the class because they are inherited from the prototype:

class A {
  constructor(name, date) {
    this.nameDateString = name + date;
  }
  someMethod() {
    return `${this.nameDateString} ${this.nameDateString}`;
  }
  addAnotherNameDateString(name, date) {
    this.nameDateString += name + date;
  }
}

const a1 = new A("Joe", new Date());
const a2 = new A("Mary", new Date());
console.log(a1.someMethod === a2.someMethod); // true

On the other hand, when using the createA function, different function objects are created every time createA is called:

const createA = (name, date) => {
  let nameDateString = name + date;
  const someMethod = () => {
    return `${nameDateString} ${nameDateString}`;
  }
  const addAnotherNameDateString = (name, date) => {
    nameDateString += name + date;
  }
  return { someMethod, addAnotherNameDateString };
}

const a1 = createA("Joe", new Date());
const a2 = createA("Mary", new Date());

console.log(a1.someMethod === a2.someMethod); // false

Objects created by createA have a larger memory imprint compared to those created by new A as they possess their own copies of function objects.

However, the code underlying these function objects will be reused by any decent JavaScript engine. For instance:

const a1 = createA("Joe", new Date());
const a2 = createA("Mary", new Date());

In this scenario, memory allocation might look something like the following diagram shows...

(For detailed explanation, refer to the original text)

Ultimately, if the memory efficiency is crucial for your application, measure the impact with real code and consider using tools like Memory tab in browser dev tools to monitor memory consumption based on your coding choices.

Answer №2

The efficiency of your code depends on the specific JavaScript engine that is running it. Some engines may be smart enough to recognize that the functions within createA are consistent but with different closures, and optimize accordingly. To determine which approach is best, it is recommended to conduct performance measurements. (As noted in the comments, most modern engines tend to optimize code sufficiently so that the underlying code object is shared among functions even when the closure varies.)

Using a class eliminates the need for the engine to make clever optimizations since the methods belong to the class's prototype. Moreover, using classes aligns more closely with current coding conventions, making it a preferable choice.

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

Using JavaScript to trigger an event when there is a change in the innerHTML or attributes

I have come across a jQuery calendar with the capability to scroll through months, and I am interested in triggering an event each time the month changes so that I can assign event listeners to every td element within the table (with days represented by ...

Directive Template with Dynamic Fields (AngularJS)

I am interested in creating a custom directive that can bind to any object, allowing me to specify the field used in the template for display. Previously, I was limited to using {{item.Name}}, but now I want the flexibility to define the display field. Cu ...

"Error: The property $notify is not found in the type" - Unable to utilize an npm package in Vue application

Currently integrating this npm package for notification functionalities in my Vue application. Despite following the setup instructions and adding necessary implementations in the main.ts, encountering an error message when attempting to utilize its featur ...

Attempting to output numerical values using Jquery, however instead of integer values, I am met with [Object object]

I am struggling to figure out how to display the value contained in my object after attempting to create a Calendar using Jquery. I attempted to use JSON.toString() on my table data, but it didn't solve the issue. Perhaps I am not placing the toString ...

Sending numerous messages from a single event using Socket.io

After an exhaustive search, I have yet to find a solution to my problem. I am attempting to send a message from the server every time it detects a file change in a specific directory. However, instead of sending just one message, it sends the same message ...

Rendering React Router server-side with client-side session information

Currently, I am working with mozilla client-sessions in conjunction with express/node. My goal is to pass my session.user to the react-router within a standard * request. Despite my efforts and attempts, I keep encountering an issue where it becomes unde ...

Showing PHP array in the JavaScript console

I have a straightforward AJAX script that sends 3 variables to an external PHP script. The external script then adds them into an array and sends the array back. I want to output this array in the JavaScript console to check if the variables are being pass ...

My code gets disrupted when I switch between ids and classes

I'm currently learning about javascript and jquery, attempting to implement various scripts. I successfully executed the following script: jQuery(document).ready(function($) { var scroll_start = 0; var startchange = $('#homepage-header' ...

Need to double tap to remove item in redux-toolkit

Trying to delete an item in Redux Toolkit, but having trouble as the remove function only works on screen. I have to press twice to delete the previous one. Here is the reducer: const noteReducer = createSlice({ name: "note", initialState: N ...

Creating an interface that accurately infers the correct type based on the context

I have an example below of what I aim to achieve. My goal is to start with an empty list of DbTransactInput and then add objects to the array. I experimented with mapped types to ensure that the "Items" in the "Put" property infer the correct data type, w ...

Saving the retrieved data from a JQuery $.post request into a JavaScript global variable

Currently utilizing Javascript and JQuery. A declaration of a Variable var RoleID=""; is stationed outside all functions. There exists a function: role_submit(){ var role=$('#emp_role').val(); var url="submitrole.php"; $.post(url, {role2: rol ...

The re-assignment of `req.session.variable` in Express-session does not carry over between two different routes

I am currently working on a basic app that allows logged in users to search and book train journeys using Express, MongoDB, Mongoose, and Express-session. The selected journeys are temporarily stored in the req.session.order variable (which I believe is gl ...

The process of displaying only the month name as the title in Full Calendar

Is there a way to display the Full Calendar title with only the month name instead of "month name year name"? Here is my code attempt: $('#calendar').fullCalendar({ header: { left: 'prev', center: 'title' ...

Utilizing VueJS to Establish a Binding Relationship with Props

One of my Vue components is named Avatar.vue, and it is used to create an avatar image based on user-defined props. The parameter imgType determines whether the image should have rounded corners or not. Here is the code: <template> <div> & ...

A guide on sending arguments to a react function component from a JSX component via onClick event handling

Below is a brief excerpt from my extensive code: import React from "react"; const Home = () => { return ( imgFilter.map((imgs) => { return ( < Col sm = "3" xs = "12" key ...

When the properties change, React Router Redux does not get rendered

I am encountering a challenge with using react router redux, where everything seems to be working well except for rendering when props change. Index.js import React from 'react'; import ReactDOM from 'react-dom'; import {Provider} fro ...

Triggering a JavaScript event with every update to the DOM marked as "completed"

I've been having some trouble with a specific task. I'm working on a script where I need to execute some functions after DOM manipulation is complete. The challenge is that I can't make changes to any other scripts on the page, as they might ...

Determine the Button's State by Monitoring Changes in the TextBox Text

I have been tasked with developing a web application for my company. The main components of the application are a button and a textbox. My goal is to allow users to input a value into the textbox, which will then be processed when they click on the button ...

What is the best way to directly send a message from a panel to a page-mod's content script?

When working with a code snippet in a Firefox addon like the one below: var pagemod = PageMod({ include: ['*'], contentScriptFile: [data.url('content.js')] }); panel = require("sdk/panel").Panel({ width: 322, height: 427, ...

What is the method to incorporate the current time into a date object and obtain its ISO string representation?

I'm using a ngbDatePicker feature to select a date, which then returns an object structured like this: {year:2020, month:12, day:03} My goal is to convert this date into an ISOString format with the current time. For example, if the current time is 1 ...